Blueprint Auth Proxy (blueprint-auth)
The auth proxy inside blueprint-manager is the single point that authenticates, authorizes, and injects tenant
identity for a Blueprint’s off-chain HTTP/gRPC endpoints (APIs, agents, gateways, etc.). Blueprints often expose such
endpoints, and in the Tangle Blueprint stack they are typically fronted by this proxy.
That proxy is implemented by the blueprint-auth crate and is the single enforcement point for:
- Authentication (API keys, OAuth assertions, mTLS)
- Authorization (scopes)
- Multi-tenancy (canonical tenant identity injection)
- Header hygiene (strip spoofable auth headers; validate forwarded headers)
This page focuses on how service users obtain credentials and how service developers consume identity safely.
Source of truth (implementation-focused):
- Auth proxy flows and endpoints: https://github.com/tangle-network/blueprint/blob/main/crates/auth/AUTH_WORKFLOW.md
- OAuth JWT bearer assertion policy: https://github.com/tangle-network/blueprint/blob/main/crates/auth/src/oauth/README.md
What It Applies To (And What It Does Not)
- Applies to: off-chain requests that go through the manager’s proxy to your service
upstream_url. - Does not apply to: on-chain jobs (
jobs submit, contract calls). On-chain callers authenticate by signing transactions.
Identity headers: service_id, x-tenant-id, x-scopes
service_id: Identifies the service behind the proxy. Minting endpoints requireX-Service-Id: <service_id>.- Tenant identity: The proxy injects
x-tenant-id(a privacy-safe hash) so upstreams can partition data safely. - Scopes: The proxy can inject
x-scopes(space-delimited) derived from an authorized token. - Trust boundary: Upstreams should treat the proxy as the only trusted source of tenant/scopes headers.
How A User Gets An Access Token
Users don’t generate v4.local... access tokens locally. They obtain them from the auth proxy by proving identity via
one of the supported mechanisms.
Option A: OAuth 2.0 JWT Bearer Assertion (Typical End-User Flow)
If your service is configured with an OAuth policy, a user can exchange a signed JWT assertion for a short-lived access token:
- The user authenticates with an issuer you trust (your IdP) and receives a signed JWT assertion containing
sub,iss,iat,exp, and a uniquejti. - The user calls the proxy:
curl -sS -X POST "http://<manager-host>:8276/v1/oauth/token" \
-H "X-Service-Id: <service_id>" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
--data-urlencode "assertion=<compact-jwt>"- The proxy verifies the assertion (signature + claims + replay protection via
jti) and returns a short-livedv4.local...token. - The user calls your service through the proxy:
curl -sS "http://<manager-host>:8276/<your-upstream-path>" \
-H "Authorization: Bearer v4.local.<...>"What your upstream receives (conceptually):
x-tenant-id: derived from the verified OAuthsub(hashed)x-scopes: a normalized scope list if allowed by your per-service policy
Option B: API Key Exchange (Service Owner / Operator Flow)
This is primarily for service owners/operators and automation:
- Owner proves control of a registered owner key (challenge/verify).
- Proxy returns a long-lived API key (
ak_...). - Owner exchanges the API key for a short-lived access token:
curl -sS -X POST "http://<manager-host>:8276/v1/auth/exchange" \
-H "Authorization: Bearer ak_<key_id>.<secret>" \
-H "Content-Type: application/json" \
-d '{"additional_headers": {"X-Tenant-Id": "optional-tenant-hint"}}'Option C: mTLS (High-Trust Environments)
If a service is configured to require client mTLS, the client authenticates using a certificate trusted by the proxy. The proxy can inject certificate identity headers (subject/issuer/serial) and an auth method header.
Multi-Tenancy: What Happens For A New User vs Existing User
From the proxy’s perspective, multi-tenancy is stateless:
- A “new user” is simply a request whose derived
x-tenant-idhas not been seen by your upstream before. - An “existing user” is one whose derived
x-tenant-idmatches previously observed requests.
The proxy is responsible for:
- Deriving/injecting a canonical
x-tenant-idafter validating the caller - Stripping any client-supplied
x-tenant-*orx-scopesheaders (prevent spoofing) - Validating/normalizing any additional forwarded headers (size, count, forbidden headers)
Your upstream is responsible for:
- Using
x-tenant-idas the partition key (database namespace, row-level filter, object prefix, etc.) - Enforcing scope checks based on
x-scopes(if your service uses scopes) - Ensuring requests cannot bypass the proxy (network policy, firewall rules, service binding to localhost/private network)
Operator Notes (Manager Defaults)
blueprint-manager runs the auth proxy by default and exposes CLI flags:
--auth-proxy-host(default0.0.0.0)--auth-proxy-port(default8276)
See: https://github.com/tangle-network/blueprint/blob/main/crates/manager/src/config/mod.rs
Configuration Status (OAuth Policy)
OAuth verification is driven by a per-service policy (allowed issuers/audiences/public keys/scopes/TTL caps)
stored by service_id.
At time of writing, the policy format and verification rules are implemented and tested, but operator-facing tooling for managing policies may be limited. Start here:
- Policy schema + rules: https://github.com/tangle-network/blueprint/blob/main/crates/auth/src/oauth/README.md