Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions components/NetworkResources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ const NETWORK_DATA = {
property: "Protocol Contracts",
value: {
type: "link",
url: "https://github.com/tangle-network/tnt-core/tree/v2",
url: "https://github.com/tangle-network/tnt-core/tree/main",
text: "github.com/tangle-network/tnt-core",
},
},
{
property: "Blueprint SDK",
value: {
type: "link",
url: "https://github.com/tangle-network/blueprint/tree/v2",
url: "https://github.com/tangle-network/blueprint/tree/main",
text: "github.com/tangle-network/blueprint",
},
},
Expand Down Expand Up @@ -109,15 +109,15 @@ const NETWORK_DATA = {
property: "Protocol Contracts",
value: {
type: "link",
url: "https://github.com/tangle-network/tnt-core/tree/v2",
url: "https://github.com/tangle-network/tnt-core/tree/main",
text: "github.com/tangle-network/tnt-core",
},
},
{
property: "Blueprint SDK",
value: {
type: "link",
url: "https://github.com/tangle-network/blueprint/tree/v2",
url: "https://github.com/tangle-network/blueprint/tree/main",
text: "github.com/tangle-network/blueprint",
},
},
Expand Down
1 change: 1 addition & 0 deletions pages/developers/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const meta: Meta = {
},
"blueprint-contexts": "Contexts",
"blueprint-runner": "Blueprint Runner",
"blueprint-auth": "Auth Proxy",
"blueprint-qos": "Quality of Service",
"p2p-networking": "P2P Networking",
"-- tooling": {
Expand Down
129 changes: 129 additions & 0 deletions pages/developers/blueprint-auth.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: Blueprint Auth Proxy
description: How blueprint-manager enforces authn/authz for off-chain HTTP/gRPC services (multi-tenancy, scopes, OAuth, mTLS).
---

# Blueprint Auth Proxy (`blueprint-auth`)

Blueprints often expose off-chain HTTP/gRPC endpoints (APIs, agents, gateways, etc.). In the Tangle Blueprint stack,
those endpoints are typically fronted by an **auth proxy** that runs inside `blueprint-manager`.

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.

## Key Concepts

- `service_id`: Identifies the service behind the proxy. Minting endpoints require `X-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:

1. The user authenticates with an issuer you trust (your IdP) and receives a signed JWT assertion containing `sub`,
`iss`, `iat`, `exp`, and a unique `jti`.
2. The user calls the proxy:

```bash
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>"
```

3. The proxy verifies the assertion (signature + claims + replay protection via `jti`) and returns a short-lived
`v4.local...` token.
4. The user calls your service through the proxy:

```bash
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 OAuth `sub` (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:

1. Owner proves control of a registered owner key (challenge/verify).
2. Proxy returns a long-lived API key (`ak_...`).
3. Owner exchanges the API key for a short-lived access token:

```bash
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-id` has not been seen by your upstream before.
- An “existing user” is one whose derived `x-tenant-id` matches previously observed requests.

The proxy is responsible for:

- Deriving/injecting a canonical `x-tenant-id` after validating the caller
- Stripping any client-supplied `x-tenant-*` or `x-scopes` headers (prevent spoofing)
- Validating/normalizing any additional forwarded headers (size, count, forbidden headers)

Your upstream is responsible for:

- Using `x-tenant-id` as 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` (default `0.0.0.0`)
- `--auth-proxy-port` (default `8276`)

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
8 changes: 4 additions & 4 deletions pages/developers/blueprint-contexts/evm-provider-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay';

# EVM Provider Context

SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/v2/crates/contexts
SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/main/crates/contexts

The `EvmInstrumentedClientContext` trait provides a standardized [alloy-rs](https://github.com/alloy-rs) EVM provider for interacting with EVM-compatible blockchain networks in your Blueprint.

Expand All @@ -15,7 +15,7 @@ The `EvmInstrumentedClientContext` trait provides a standardized [alloy-rs](http
The `EvmInstrumentedClientContext` trait provides access to an EVM provider:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/contexts/src/instrumented_evm_client.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/contexts/src/instrumented_evm_client.rs"
fromLine={3}
toLine={6}
title="EvmInstrumentedClientContext Trait Definition"
Expand All @@ -28,7 +28,7 @@ The `EvmInstrumentedClientContext` trait provides access to an EVM provider:
First, define your context struct that implements the `EvmProviderContext` trait:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={13}
toLine={22}
title="EVM Provider Context Definition"
Expand All @@ -39,7 +39,7 @@ First, define your context struct that implements the `EvmProviderContext` trait
You can then use this context to access EVM provider parameters:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={36}
toLine={36}
title="Accessing EVM Provider Parameters"
Expand Down
4 changes: 2 additions & 2 deletions pages/developers/blueprint-contexts/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
title: Introduction to Contexts
---

SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/v2/crates/contexts
SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/main/crates/contexts

## What is a Context?

In the [Blueprint SDK](https://github.com/tangle-network/blueprint/tree/v2), a Context holds utilities and dependencies that a job may need that aren't direct inputs. Think of it as a container for all the external resources and services your job requires to function.
In the [Blueprint SDK](https://github.com/tangle-network/blueprint/tree/main), a Context holds utilities and dependencies that a job may need that aren't direct inputs. Think of it as a container for all the external resources and services your job requires to function.

A Context can include various elements such as:

Expand Down
8 changes: 4 additions & 4 deletions pages/developers/blueprint-contexts/keystore-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay';

# Keystore Context

SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/v2/crates/contexts
SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/main/crates/contexts

The `KeystoreContext` trait provides a standardized interface for accessing, managing, and signing using cryptographic keys in your Blueprint.

Expand All @@ -21,7 +21,7 @@ The `KeystoreContext` trait provides access to a `Keystore` that implements the
- Key Import/Export - Import existing keys and export key data

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/contexts/src/keystore.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/contexts/src/keystore.rs"
fromLine={4}
toLine={7}
title="KeystoreContext Trait Definition"
Expand All @@ -34,7 +34,7 @@ The `KeystoreContext` trait provides access to a `Keystore` that implements the
First, define your context struct that implements the `KeystoreContext` trait:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={13}
toLine={22}
title="Keystore Context Definition"
Expand All @@ -45,7 +45,7 @@ First, define your context struct that implements the `KeystoreContext` trait:
You can then use this context to access the keystore and perform key operations:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={35}
toLine={35}
title="Accessing Keystore Functionality"
Expand Down
29 changes: 15 additions & 14 deletions pages/developers/blueprint-contexts/tangle-client-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,47 @@ import GithubFileReaderDisplay from '/components/GithubFileReaderDisplay';

# Tangle Client Context

SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/v2/crates/contexts
SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/main/crates/contexts

The `TangleEvmClientContext` trait provides a standardized interface for interacting with the Tangle EVM protocol from a Blueprint. It exposes a typed `TangleEvmClient` configured from the blueprint environment.
The `TangleClientContext` trait provides a standardized interface for interacting with the Tangle protocol from a
Blueprint. It exposes a typed `TangleClient` configured from the blueprint environment.

## Context Summary

The `TangleEvmClientContext` trait provides access to an EVM client that enables:
The `TangleClientContext` trait provides access to a client that enables:

- Transaction submission to core protocol contracts
- Service and operator state queries
- Job submission and result reporting
- Access to operator identity and keystore-backed signing

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/contexts/src/tangle_evm.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/contexts/src/tangle.rs"
fromLine={1}
toLine={44}
title="TangleEvmClientContext Trait Definition"
toLine={70}
title="TangleClientContext Trait Definition"
/>

## Using the Context

### 1. Define Your Context

First, define your context struct that implements the `TangleEvmClientContext` trait:
First, define your context struct that implements the `TangleClientContext` trait:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={13}
toLine={22}
title="Tangle Client Context Definition"
/>

### 2. Access Tangle EVM Client Functionality
### 2. Access Tangle Client Functionality

You can then use this context to access the client and interact with the Tangle EVM protocol:
You can then use this context to access the client and interact with the Tangle protocol:

<GithubFileReaderDisplay
url="https://github.com/tangle-network/blueprint/blob/v2/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={35}
toLine={35}
title="Accessing Tangle EVM Client Functionality"
url="https://github.com/tangle-network/blueprint/blob/main/crates/macros/context-derive/tests/ui/basic.rs"
fromLine={25}
toLine={32}
title="Accessing Tangle Client Functionality"
/>
Loading