YAML configuration reference

This document describes the deployment authorization YAML only. Process flags and SERVICEAUTH_* environment variables belong in USAGE.md. Runtime catalog objects such as audiences, resources, groups, and grants belong in API.md.

The file is one strict YAML document with version: 1. Unknown fields, duplicate keys, and multiple YAML documents are rejected. The validated document is canonicalized and fingerprinted; that fingerprint is tied to the active OpenFGA model during migrate and must match during run.

Top-level shape

version: 1
token_sources: {}
permissions: {}
roles: {}
resources: {}
management:
  permissions: {}

The recognized top-level sections are version, token_sources, permissions, roles, resources, and optional management. version must be 1; permissions and roles must be non-empty. token_sources and resources may be empty when a deployment does not use external token sources or application resources. Omitted management permission entries use the standard names described below.

Identifiers for token sources, roles, resource types, and relationship names use lowercase letters, digits, and underscores and begin with a letter. Permission names contain at least two lowercase dot-separated segments. principal, group, and audience are reserved resource concepts and cannot be declared under resources; audience is available as a permission target.

version

The schema version integer. The current and only accepted value is 1.

token_sources

Defines which external JWT issuers may establish principals.

token_sources:
  corporate:
    issuer: https://id.example.com
    keys:
      discovery: true
    algorithms: [RS256]
    identity:
      subject_claim: sub
      prefix: corporate
    validation:
      audience:
        any_of: [https://auth.example.com]
      claims:
        organization:
          equals: example
    propagate_claims:
      email:
        from: email

Each source has these attributes:

Attribute Purpose and constraints
issuer Absolute HTTPS issuer URL. The JWT issuer must match this configured value.
keys Exactly one key mode: discovery, jwks_url, inline jwks, or PEM public_key. Key modes are mutually exclusive.
keys.discovery Set true to discover issuer metadata and JWKS. Discovery verifies issuer equality.
keys.jwks_url Absolute HTTPS JWKS URL when keys are maintained at a known endpoint.
keys.jwks Inline JWKS object for deployments that distribute key material with the configuration.
keys.public_key PEM-encoded public key for a static external signing key. This is public verification material, not a private signing key.
algorithms Non-empty allowlist of supported asymmetric JWT algorithms: RS256, RS384, RS512, ES256, ES384, or ES512.
identity.subject_claim External JWT claim used as the subject. It is required and is read before the principal is normalized.
identity.prefix Unique lowercase principal prefix used to distinguish subjects from different issuers.
validation Optional audience and claim rules evaluated before identity is accepted.
propagate_claims Optional allowlist of external claims to copy to platform JWT claims. Each output maps to a source claim using from.

Remote keys are cached. An unknown key ID may cause a bounded refresh, but a token is never trusted merely because the issuer is configured. Claim propagation cannot overwrite reserved platform claims such as iss, sub, aud, exp, iat, nbf, jti, act, permissions, or authorization_context.

Validation matchers

validation.audience accepts one matcher. Each validation.claims.<name> entry also accepts exactly one matcher operation:

Matcher Meaning
exists: true or false Require the claim to exist or not exist.
equals: value Require an exact scalar/structured value.
not_equals: value Reject an exact value.
one_of: [values] Match one of the listed values.
any_of: [values] Match any configured accepted value; commonly used for audiences.
prefix: text Require a string prefix.
suffix: text Require a string suffix.
regex: expression Match a valid regular expression.
contains: value Require the claim to contain the value according to its supported representation.

Do not combine operations in one matcher. Empty one_of or any_of lists and invalid regular expressions are rejected.

permissions

Defines the capabilities that applications and management routes can request. Each permission must apply to at least one resource type, and every permission must be included by at least one role.

permissions:
  api.invoke:
    resources: [audience]
  document.read:
    resources: [document]
  document.write:
    resources: [document]

resources is a non-empty list of declared resource types or the intrinsic audience type. A permission may apply to more than one type. The same permission name can therefore be evaluated at different resource kinds, but a grant is effective only for the applicable target type.

roles

Defines named bundles of permissions used by runtime grants and bootstrap.

roles:
  editor:
    permissions: [api.invoke, document.read, document.write]

Every role needs at least one known permission. Role names are identifiers and role membership is not itself an application authorization contract; application callers should use permission names.

resources

Defines application resource types, their relationships, and inherited permissions. Runtime instances are created through the management API.

resources:
  folder:
    relationships: {}
  document:
    relationships:
      parent:
        targets: [folder]
        cardinality: one
        required: false
    inheritance:
      - relationship: parent
        permissions: [document.read]

Resource attributes

Attribute Purpose and constraints
relationships Map of relation names to allowed target types and lifecycle constraints. It may be empty.
relationships.<name>.targets Non-empty list of declared resource types. Unknown or duplicate targets are rejected.
relationships.<name>.cardinality one permits one target; many permits multiple targets.
relationships.<name>.required Whether lifecycle validation requires a relationship value.
inheritance Optional list of permissions inherited through a relationship.
inheritance[].relationship Relationship defined on the same resource type.
inheritance[].permissions Non-empty list of known permissions that applies to the current resource type.

Relationship names cannot use reserved role_ or permission_ prefixes. The service rejects invalid references, self-inconsistent inheritance, unsupported cardinality, and nested-group cycles. Resource relationships are runtime data; the YAML defines what is legal, not which instances currently exist.

management

Configures the permission required by each family of authenticated management endpoints. This is deployment policy layered on top of the authorization model and is the explicit bootstrap escape from the meta-permission problem.

management:
  permissions:
    audiences:
      read: management.audiences.read
      write: management.audiences.write
    resources:
      read: management.resources.read
      write: management.resources.write
    groups:
      read: management.groups.read
      write: management.groups.write
    grants:
      read: management.grants.read
      write: management.grants.write

The supported families are audiences, resources, groups, and grants; each may define read and write. An omitted value uses the corresponding conventional name:

Route family Read default Write default
audiences management.audiences.read management.audiences.write
resources management.resources.read management.resources.write
groups management.groups.read management.groups.write
grants management.grants.read management.grants.write

Every explicitly configured permission must exist under permissions and must apply to audience. The bootstrap role must include a management permission that applies to audience; when custom management permissions are used, ensure the bootstrap role includes the intended custom permission.

The conventional default names are not generated as implicit permission definitions. If a route uses a default, declare that permission under permissions and include it in the role that should receive the corresponding management capability.

Validation and lifecycle

validate is the safe preflight for this document. migrate compiles and activates the resulting model. run verifies the same fingerprint and fails closed if the database has not been migrated to it.

Changing YAML is a schema change, not a runtime catalog mutation. Review permission applicability, role coverage, relationship targets, inheritance, token trust, and bootstrap authority together. Never place a private platform signing key in this file; local private key paths and KMS key references are process settings described in USAGE.md.