Skip to content

Connecting to Veho Internal APIs

⚠️ Work in Progress

This feature is currently being implemented and is not yet available. The Veho Data Proxy is under active development by the Platform team. Do not attempt to use it in apps yet — the integration is not complete and the behavior may change before launch.

This documentation describes the intended design. We will remove this notice when the feature is ready.

Vulcan apps will be able to read from Veho's internal APIs — AppSync, API Gateway, and more — without any credentials in the app code. Authentication will be handled entirely by the Vulcan platform.

Access is not automatic. Vulcan can only reach internal APIs that have explicitly granted it access and have been registered in Vulcan's catalog by the Platform team. If your API is not registered, Vulcan apps cannot reach it, regardless of network or IAM configuration.

Why the proxy exists

Vulcan-generated apps never call Veho internal APIs directly. Every request must flow through the Veho Data Proxy. This is by design and cannot be worked around.

The proxy is the platform's central control point for all access to Veho production APIs. It exists to:

  • Handle authentication without exposing credentials. IAM roles and secrets live only inside the Vulcan platform. App code never sees them, and they never reach the browser.
  • Enforce a registration gate. An API must be explicitly added to the catalog by the Platform team before any app can reach it. There is no path to a Veho internal API that bypasses this check — if a source is not registered, the proxy returns 404 regardless of network reachability or IAM configuration.
  • Apply guardrails uniformly. Because all traffic flows through a single proxy, platform-level protections apply to every app automatically. Rate limiting (60 req/min, 2,000 req/day per app) is one example. Future guardrails — query complexity limits, field-level access control, anomaly detection, cost attribution — can be added here without touching any app code.
  • Protect Veho production APIs from abuse. User-generated apps run untrusted code written by many different teams. Without a proxy, a single misconfigured app (a polling loop, a cron job gone wrong, a load test accidentally pointed at prod) could generate uncapped load on AppSync, STS, and the downstream services they call. The proxy is the mechanism that ensures this cannot happen.

How it works

When a Vulcan app calls a Veho internal API, the request flows through a secure platform proxy:

App (browser) → Vulcan app Worker → Veho Data Proxy → Your API
  1. The app sends an authenticated request to the proxy using a signed app token
  2. The proxy checks its internal catalog — if the source is not registered, the request is rejected with a 404
  3. Rate limiting is applied per app — requests that exceed the quota are rejected with 429 before any upstream call is made
  4. For registered sources, the proxy obtains credentials (either via AWS STS AssumeRole or a stored secret) and forwards the request with the correct auth headers
  5. The response returns through the proxy to the app

No credentials ever live in app code or reach the browser. They exist only inside the Vulcan platform.

Currently available sources

Only APIs explicitly registered in Vulcan's catalog are accessible. Today that is:

Source nameWhat it isProtocol
supergraphVeho platform supergraph — merged AppSync GraphQL API covering 20+ internal services (drivers, facilities, routes, packages, offers, markets, and more)GraphQL

If the API you need is not in this list, Vulcan cannot access it yet. See Getting your API registered below.

How apps use it

Once an API is registered, just describe what you need in chat:

"Show me a list of active drivers from the supergraph" "Build a map using facility data from the Veho API"

The AI generates the correct proxy calls automatically — no credentials or config required.


Getting your API registered

This is a two-party process. Both steps are required before Vulcan can access your API:

  1. Your team grants Vulcan access — by creating an IAM role Vulcan can assume, or by sharing a secret
  2. The Platform team registers the source in Vulcan's catalog and, for secret-auth sources, stores the secret as a Wrangler secret

The Platform team cannot complete registration without your IAM role or secret.

Reach out in #eng_product_platform_team to start.


Use this for AppSync, API Gateway, and any other AWS service that supports IAM authentication. Vulcan handles STS AssumeRole and SigV4 signing automatically.

Step 1 — Create the IAM role

In the AWS Console, go to IAM → Roles → Create role and choose Custom trust policy.

Paste this trust policy exactly:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::115383865810:user/vulcan-platform"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

This grants Vulcan's IAM user — arn:aws:iam::115383865810:user/vulcan-platform — permission to assume the role. That is the only principal that needs trust.

Step 2 — Attach a permissions policy

Grant the role the minimum permissions it needs to call your API.

For an AppSync API:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "appsync:GraphQL",
      "Resource": "arn:aws:appsync:<region>:<account-id>:apis/<api-id>/*"
    }
  ]
}

Find the API ID in the AppSync console under your API → Settings.

For an API Gateway REST API:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:<region>:<account-id>:<api-id>/*"
    }
  ]
}

Scope the resource to specific stages or routes if you want tighter access (e.g. .../<api-id>/prod/GET/items).

Step 3 — Name the role

Use a name like vulcan-<your-service>-read so the purpose is clear in CloudTrail. Examples:

  • vulcan-dispatch-api-read
  • vulcan-routing-appsync-read
  • vulcan-offers-api-read

Step 4 — Share with the Platform team

Post in #eng_product_platform_team with:

  • The role ARN (e.g. arn:aws:iam::123456789012:role/vulcan-dispatch-api-read)
  • Your API endpoint URL
  • Protocol: GraphQL or REST
  • A one-line description of what the API provides

That is everything the Platform team needs to complete the registration.


Option B — Static secret or API key

Use this for non-AWS APIs that authenticate via a Bearer token, API key, or other static header value.

Share the following securely with the Platform team (use 1Password or a direct Slack DM — not a public channel):

  • The secret value itself
  • The API endpoint URL
  • The header name the secret should be sent in (e.g. Authorization, X-Api-Key)
  • The prefix, if any (e.g. Bearer — include the trailing space — or blank for a raw key)

What happens after registration

Option A — IAM Role

The Platform team enters your source directly in the admin UI at /admin/veho-sourcesno code change or deploy required. They enter the source name, your endpoint URL, and the role ARN. The entry is stored in Vulcan's KV catalog and takes effect immediately.

After registration:

  • Vulcan users can access your API by describing what they want in chat
  • The AI generates the correct proxy calls automatically
  • No user ever handles credentials

All access is authenticated and audited. IAM-based sources log every AssumeRole call to CloudTrail under the session name vulcan-platform.

Option B — Static secret

Because the actual secret value cannot be stored in KV, the Platform team:

  1. Runs wrangler secret put <SECRET_ENV_VAR_NAME> to store the value in the Vulcan Worker — this requires a deploy
  2. Adds the source in the admin UI at /admin/veho-sources, referencing the env var name (not the value)

Until the deploy is complete, Vulcan cannot reach your API.


Multiple environments

The KV-backed catalog makes it straightforward to point Vulcan at different environments of your API — dev, staging, production — without any code change. Each environment is registered as a separate named source (e.g. my-api, my-api-staging, my-api-dev). Apps call the specific source they need by name.

For IAM-role sources this is entirely self-service for the Platform team — just add new entries in /admin/veho-sources. No deploy required.


Rate limits

Every Vulcan app that calls a Veho internal API is subject to platform-level rate limits. These exist to prevent any single app from overwhelming Veho's production services (AppSync, STS, and the downstream resolvers they fan out to).

Default limits

WindowLimit
Per minute60 requests
Per day2,000 requests

Limits apply per app (per project), not per user. Two different apps owned by the same person each get their own independent quota.

What you'll see when a limit is hit

The proxy returns 429 Too Many Requests with:

Retry-After: 42
X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 0
X-RateLimit-Limit-Day: 2000
X-RateLimit-Remaining-Day: 1854

Retry-After tells you how many seconds until the current window resets. Every successful response also includes X-RateLimit-* headers so you can monitor your remaining quota.

Why these limits exist

The Veho supergraph proxies requests to live production APIs. There is no sandbox — every query hits real data and real infrastructure. Without guardrails, a single app with a tight polling loop, a misconfigured cron job, or a UI that fires queries on every keystroke could generate hundreds of requests per minute and degrade the supergraph for everyone.

The limits are intentionally generous for exploratory and development use:

  • 60 req/min is 1 request per second sustained — plenty for a playground, a dashboard, or an interactive tool.
  • 2,000 req/day gives comfortable room for development cycles and moderate production usage.

Raising your limits

If your app has a legitimate need for higher throughput (for example, an ops dashboard running on a scheduled job or a data pipeline), contact the Platform team in #eng_product_platform_team. Limits can be raised per-app without a deploy.


Questions

Contact the Platform team in #eng_product_platform_team or reach out directly to Rowell Belen or Timothy Mathison.

Built by the Veho Developer Platform team