> ## 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](/constitution/http-and-events)). |
| 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](/adr/0098-actions-are-the-unit)). | **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](/adr/0012-code-host-and-ci)). |
| SEC7 | **Encryption** in transit everywhere. At rest through the provider. Application secrets only through the secret store ([Secrets](/constitution/secrets)). | **Planned.** |

## 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](/adr/0088-tenancy-free-pool-pro-silo-and-scope), 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](/adr/0125-constitution-amended-to-match-accepted-adrs): 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.


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