Skip to content

Commit e71bb30

Browse files
committed
Review updates
1 parent 9c7a569 commit e71bb30

26 files changed

Lines changed: 1739 additions & 419 deletions

docs/content/docs/api/authentication.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ email = "email" # Use 'email' claim
102102
org_id = "org_id" # Custom claim for organization
103103
```
104104

105+
### Per-Org JWT Validation
106+
107+
In multi-tenant deployments, each organization can configure their own identity provider via the Admin UI. JWTs from per-org IdPs are automatically validated — the gateway decodes the `iss` claim and routes the token to the correct org's validator. No global `[auth.gateway.jwt]` config is needed for this to work.
108+
109+
See [Per-Org JWT Routing](/docs/authentication#per-org-jwt-routing) for details.
110+
105111
### Supported Algorithms
106112

107113
| Algorithm | Description |
@@ -134,6 +140,12 @@ With this configuration:
134140
2. If `Authorization: Bearer` header is present with JWT format, validate as JWT
135141
3. If `Authorization: Bearer` header is present with `gw_` prefix, validate as API key
136142

143+
<Callout type="info">
144+
The `[auth.gateway.jwt]` section is optional in multi-auth mode. When per-organization SSO is
145+
configured, each org's SSO config provides JWT validation automatically. Omit `[auth.gateway.jwt]`
146+
if all JWT validation should come from per-org configs.
147+
</Callout>
148+
137149
## Error Responses
138150

139151
All authentication errors return HTTP 401 with a consistent error format:

docs/content/docs/authentication.mdx

Lines changed: 533 additions & 0 deletions
Large diffs are not rendered by default.

docs/content/docs/configuration/auth.mdx

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Callout } from "fumadocs-ui/components/callout";
88
This page is the **configuration reference** for authentication settings in `hadrian.toml`. For conceptual overviews and guides, see:
99

1010
<Cards>
11-
<Card title="Authentication Overview" href="/docs/features/authentication" />
11+
<Card title="Authentication Overview" href="/docs/authentication" />
1212
<Card title="SSO Admin Guide" href="/docs/features/sso-admin-guide" />
1313
<Card title="Authorization Guide" href="/docs/features/authorization" />
1414
</Cards>
@@ -265,6 +265,26 @@ audience = "hadrian"
265265
jwks_url = "https://auth.example.com/.well-known/jwks.json"
266266
```
267267

268+
<Callout type="info">
269+
The `[auth.gateway.jwt]` section is **optional** in multi-auth mode. When per-organization SSO is
270+
configured, each org's SSO config automatically provides JWT validation on `/v1/*` endpoints. If
271+
`[auth.gateway.jwt]` is omitted, only per-org SSO configs and API keys are used — there is no
272+
global JWT fallback. See [Per-Org JWT Routing](/docs/authentication#per-org-jwt-routing).
273+
</Callout>
274+
275+
**Multi-auth with API keys only (per-org JWT):**
276+
277+
```toml
278+
[auth.gateway]
279+
type = "multi"
280+
281+
[auth.gateway.api_key]
282+
key_prefix = "gw_"
283+
cache_ttl_secs = 300
284+
285+
# No [auth.gateway.jwt] — per-org SSO configs provide JWT validation
286+
```
287+
268288
**Request Examples:**
269289

270290
```bash
@@ -1356,3 +1376,57 @@ slug = "default"
13561376
name = "Default Organization"
13571377
admin_identities = ["admin@example.com"]
13581378
```
1379+
1380+
### Multi-Org with Per-IdP API Authentication
1381+
1382+
Each organization configures their own identity provider via the Admin UI. No global `[auth.gateway.jwt]` is needed — per-org SSO configs automatically enable JWT validation on `/v1/*` endpoints.
1383+
1384+
```toml
1385+
[auth.gateway]
1386+
type = "multi"
1387+
1388+
[auth.gateway.api_key]
1389+
key_prefix = "gw_"
1390+
cache_ttl_secs = 300
1391+
1392+
# No [auth.gateway.jwt] section.
1393+
# Per-org SSO configs provide JWT validation for each org's IdP.
1394+
1395+
[auth.admin]
1396+
type = "session"
1397+
secret = "${SESSION_SECRET}"
1398+
1399+
[auth.admin.session]
1400+
secure = true
1401+
same_site = "lax"
1402+
1403+
[auth.rbac]
1404+
enabled = true
1405+
default_effect = "deny"
1406+
1407+
[[auth.rbac.policies]]
1408+
name = "super-admin"
1409+
resource = "*"
1410+
action = "*"
1411+
condition = "'super_admin' in subject.roles"
1412+
effect = "allow"
1413+
priority = 100
1414+
1415+
[[auth.rbac.policies]]
1416+
name = "org-isolation"
1417+
resource = "*"
1418+
action = "*"
1419+
condition = "context.org_id in subject.org_ids"
1420+
effect = "allow"
1421+
priority = 10
1422+
1423+
[auth.bootstrap]
1424+
api_key = "${HADRIAN_BOOTSTRAP_KEY}"
1425+
auto_verify_domains = ["acme.com", "globex.io"]
1426+
```
1427+
1428+
<Callout type="info">
1429+
After deploying, use the bootstrap API key to create organizations and their SSO configs. Once SSO
1430+
is configured, each org's users can authenticate with both the web UI (via SSO login) and the API
1431+
(via JWT tokens from their org's IdP).
1432+
</Callout>

0 commit comments

Comments
 (0)