Proxy

STACK's Layer 2. Every outbound HTTP call an agent makes routes through a single proxy endpoint. The proxy verifies the passport, enforces scope and parameter constraints, injects the credential at the wire, and forwards the call upstream. The agent code never holds the raw secret.

The proxy is the one place an integration cannot skip. Any outbound call bypassing the proxy is outside STACK's guarantees - the passport, the detectors, and the audit chain all depend on the call landing at /v1/proxy.

Request shape

One endpoint, one header, one body. The X-Passport-Tokenheader carries the signed passport; the body describes the upstream call exactly as you would send it directly.

text
POST /v1/proxy
X-Passport-Token: eyJhbGciOi...
Authorization: Bearer sk_live_...

{
  "service": "slack",
  "method": "POST",
  "url":    "https://slack.com/api/chat.postMessage",
  "headers": { "Content-Type": "application/json" },
  "body":    { "channel": "C0123", "text": "hi" }
}

Call pipeline

Every proxy request walks through the same ordered checks. Any failure aborts before the upstream call is issued.

  • 1. Verify passport signature, expiry, revocation state
  • 2. Tier + overage check (proxy call counts against the operator's monthly allowance)
  • 3. Scope check - service must appear in intent_services or the passport's granted providers
  • 4. Parameter constraints - every constraint on the matching ServiceScope must pass
  • 5. Credential injection - decrypt the credential server-side, build auth headers
  • 6. URL resolution - substitute any {{instance_url}} / {{account_id}} placeholders
  • 7. Forward upstream; enforce response size (10 MB) and request timeout (30s)
  • 8. Emit scope_drift score and write audit row (layer: vault, action: credential.proxy)

What the proxy enforces

  • Service scope - only services in the passport can be reached. Anything else throws credential_outside_scope and a 403 FORBIDDEN.
  • Parameter constraints - see /docs/concepts/constraints. Can tighten to a specific channel, repo, customer ID, or regex-matched URL path.
  • Response size - capped at 10 MB. Larger upstream responses are rejected.
  • Request timeout - 30 seconds. Upstream hangs return 504.
  • Revocation - a revoked passport fails verification before the upstream call is made.

Credential injection

Credentials live encrypted in the vault (KMS envelope encryption). At step 5, the proxy decrypts in-memory, builds the upstream auth header per the provider's convention (OAuth Bearer, basic, custom HMAC, etc.), and attaches it to the forwarded request. The agent never sees the plaintext credential. Every decryption is audited.

Agent credential access modes

Agents declare credential_access to scope how they can reach services. The proxy honours the mode at verify time.

  • direct - agent can both retrieve credentials (/v1/credentials/:provider) and use the proxy
  • proxy_preferred - both paths work but the proxy is the recommended default
  • proxy_only - credential retrieval is rejected; only the proxy path is allowed

Related

  • /docs/concepts/passports - what verify checks
  • /docs/concepts/constraints - parameter-level rules enforced at step 4
  • /docs/concepts/intents - named shortcut constraints
  • /docs/concepts/detectors - scope_drift scoring that runs at step 8
  • /docs/api/proxy - complete endpoint reference
stack | docs