# Authorization

Grant an app only the named Ferrite resources, routes, and operations it needs, then enforce user and tenant policy in the app.

Ferrite uses capability-scoped authority for platform resources. Your app uses
subjects, roles, tenant membership, ownership, and assurance for product-level
authorization. Keep those two layers explicit.

## Platform capabilities

Every binding in `ferrite.json` names a resource and kind. Ferrite injects the
corresponding handle only after admission and issuance. A function cannot open
another store, queue, blob space, or outbound socket by guessing its name.

```json filename="ferrite.json"
{
  "services": [
    { "name": "shop-orders", "primitive": "store" },
    { "name": "shop-jobs", "primitive": "queue" }
  ],
  "applications": [{
    "name": "shop",
    "artifact_key": "apps/shop@v1",
    "artifact_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
    "bindings": [
      { "handle": "orders", "kind": "store", "service": "shop-orders" },
      { "handle": "jobs", "kind": "queue", "service": "shop-jobs" }
    ]
  }]
}
```

Use separate resources or attenuated rights when a worker needs less authority
than the public request handler.

## Product authorization

Resolve the authenticated subject and tenant, then check the exact domain
action. An authenticated customer may read only their orders; a support agent
may read tickets in assigned tenants; a booking staff member may administer
only their calendar.

Recheck authorization after step-up and on every request. Do not trust a role
copied into browser state or agent context.

## Agent boundaries

Remote MCP requires an explicit delegated scope. WebMCP can call the same-origin
API through the user’s browser session, but it never receives the cookie.
Anonymous tools must be limited to genuinely public data.

## Revocation

Capability tokens carry epochs so policy changes can invalidate old authority.
User sessions carry credential and authorization generations. A role, factor,
password, or SCIM deactivation updates the generation and denies stale sessions
on the next check.

See [Authentication](/developers/authentication/) and
[Secrets & Egress](/developers/secrets-egress/).
