> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> One authenticated principal per request, server-side authorization, audit, data classification and supply-chain controls.

> [!NOTE]
>
> Stackra has no deployed service yet. These laws bind the first service that authenticates a user.
> Controls that need a service are marked planned.

## Laws

| # | Law | Enforcement |
| - | - | - |
| SEC1 | **One authenticated principal per request.** A single auth handler resolves the caller once. Handlers read it from the request context, never from body, query or client headers. `auth: true` is the default. A public endpoint is a documented exception (health, signed webhooks, public content). | **Planned.** Lint rule for undocumented `expose` without auth, with the first service API ([HTTP and events](https://docs.stackra.figentra.com/constitution/http-and-events.md)). |
| SEC2 | **Authorization is server-side**, on every command and query. A client may hide what a user cannot do. It never decides. | **Planned.** Reviewed by the security-tenancy reviewer until a policy engine exists. |
| SEC3 | **Every state change emits an audit record**: actor, tenant, target, before and after references, correlation id. Every action's pipeline ends in an audit step, and the record carries the full `Actor` with its `onBehalfOf` chain, so an agent action names the agent and the human it acted for ([0098](https://docs.stackra.figentra.com/adr/0098-actions-are-the-unit.md)). | **Planned.** The pipeline-order test of 0098. |
| SEC4 | **Every data field has a classification**: `internal`, `confidential` or `pii`. PII is redacted from logs, events and errors. Each member's `AGENTS.md` carries a PII table, even if it says "none". | **Partial.** The validator checks that the PII table exists. Redaction is checked by review. |
| SEC5 | **Rate limits** on public and AI endpoints. **Budgets** on AI usage per tenant. | **Planned.** |
| SEC6 | **Supply chain is pinned.** Versions come only from catalogs. Lifecycle scripts are allow-listed. Cache artifacts are signed. Secrets are scanned on every commit. | **Partial.** Catalog check and strict mode in the validator, signed Turborepo cache in `turbo.jsonc`, gitleaks at pre-commit. CodeQL, workflow linting and dependency review arrive with CI ([ADR 0012](https://docs.stackra.figentra.com/adr/0012-code-host-and-ci.md)). |
| SEC7 | **Encryption** in transit everywhere. At rest through the provider. Application secrets only through the secret store ([Secrets](https://docs.stackra.figentra.com/constitution/secrets.md)). | **Planned.** |
| SEC8 | **One identity provider.** ZITADEL is the identity provider for every product and for Figentra OS. Identity code is provider-neutral ([0206](https://docs.stackra.figentra.com/adr/0206-zitadel-is-the-identity-provider-and-stackra-identity-is-provider-neutral.md)). A level L3 or L4 action needs a step-up, and the refusal is `step_up_required` ([0207](https://docs.stackra.figentra.com/adr/0207-authentication-assurance-and-machine-identities.md)). Operator access to production is break-glass only ([0188](https://docs.stackra.figentra.com/adr/0188-operator-access-and-the-encryption-key-hierarchy.md)). | **Planned.** The provider test in `@stackra/identity`, and the step-up test in the action pipeline. |
| SEC9 | **The pipeline order is fixed.** Apps toggle and parameterise gates; they never reorder them ([0138](https://docs.stackra.figentra.com/adr/0138-pipeline-order-is-fixed.md)). Every action is audited through the action runtime contract ([0136](https://docs.stackra.figentra.com/adr/0136-action-runtime-contract.md)) and the audit policy ([0212](https://docs.stackra.figentra.com/adr/0212-audit-evidence-access-logs-hash-chain-and-retention.md)). | **Planned.** The pipeline-order test of 0138. |

## Effective permission

When an authorization system exists, every service resolves permissions the same way. Do not invent a variant.

```text theme={"system"}
effective(principal, tenant, activeScope) =
    grants      live grants for (principal, tenant)      # not expired, not revoked
    applicable  grants whose scope path contains activeScope  # Pro scope driver; otherwise tenant-wide
    perms       union of role permissions over applicable
                  limited to entitled features
                  limited to token abilities            # API keys only
```

* Results are cached per `(principal, tenant, scope, grantsVersion)`. Any change to grants or roles bumps `grantsVersion`.
* The check is shaped `check(subject, relation, object)` so the engine behind it can be replaced without touching callers. Free `@stackra/iam` resolves RBAC with no scope dependency; the scope tree and the relation engine are Pro drivers behind the same `check()` ([0088](https://docs.stackra.figentra.com/adr/0088-tenancy-free-pool-pro-silo-and-scope.md), owner decision S3).
* A cross-tenant miss is `notFound`, never `permissionDenied`.

## Threat model template

Each service that handles user data keeps a `docs/threat-model.md` in its member folder with three tables. A row with no control is a backlog item, not a gap to forget.

| Section | Columns |
| - | - |
| Assets | asset, where it lives, class (`internal`, `confidential`, `pii`, `secret`) |
| Trust boundaries | numbered list: client to gateway, service to service, service to database, any third party |
| Threats and controls | threat, control today, open work |

## History

* 2026-10-20, [0125](https://docs.stackra.figentra.com/adr/0125-constitution-amended-to-match-accepted-adrs.md): SEC3 audit runs in the action pipeline with the 0098 actor chain; the scope step of the effective-permission formula applies only with the Pro scope driver.
* 2026-10-20, [0229](https://docs.stackra.figentra.com/adr/0229-constitution-amended-for-the-2026-10-20-decisions.md): ZITADEL, step-up, break-glass and the fixed pipeline became SEC8 and SEC9 ([0206](https://docs.stackra.figentra.com/adr/0206-zitadel-is-the-identity-provider-and-stackra-identity-is-provider-neutral.md), [0207](https://docs.stackra.figentra.com/adr/0207-authentication-assurance-and-machine-identities.md), [0188](https://docs.stackra.figentra.com/adr/0188-operator-access-and-the-encryption-key-hierarchy.md), [0138](https://docs.stackra.figentra.com/adr/0138-pipeline-order-is-fixed.md)).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.