Identity Compatibility Mode
This switch, and the decision shadow mode beside it, do not exist in v11. If you are upgrading from v10.x, read the v10 → v11 Migration Guide. The rest of this page says what the switches were, what replaced them and what to change before you upgrade.
What the switches were
From v10.2.0 (identity) and v10.3.0 (decisions) to v10.4.x, AxonFlow ran its ADR-065 identity and decision model beside the legacy system, behind two switches, and recorded where the two disagreed:
| Switch | What it did in v10.x |
|---|---|
AXONFLOW_IDENTITY_COMPAT_MODE (off, shadow, enforce), and the per-organization compat_mode identity setting | Ran each credential through the ADR-065 identity plane beside legacy authentication. shadow recorded the disagreements; enforce also refused what the identity plane did not admit. |
AXONFLOW_DECISION_SHADOW_MODE (off, shadow, enforce), and the per-organization decision_shadow_mode setting | Ran the ADR-065 decision engine beside the legacy policy engines. shadow recorded the disagreements; enforce let the new engine decide a small number of planes for that organization. |
Both defaulted to off, so a deployment that never set them never ran the new model at all.
What changed in v11
The new model is the only one. One policy decision engine decides every governed request on every enforcement plane, for every organization, with no switch to turn it on and none to turn it off. The Policy and Identity Control Plane describes what decides a request and what each decision records.
Nothing is compared any more. The v10.x modes existed to measure the new model against the old one. The two are different models, v11 promises no parity between them, and the comparison observers are removed with the modes. Where a request is decided differently from v10.x, that is intended behaviour, described in the migration guide, not a divergence to investigate.
A deployment that still sets one of the switches refuses to start. The variables below are not silently ignored: an operator who set one had a reason, and a setting that quietly stopped meaning anything is worse than a process that says so. A set, non-empty value refuses and the boot message names it; an empty value boots, so a file that passes one through empty is fine.
AXONFLOW_IDENTITY_COMPAT_MODE,AXONFLOW_IDENTITY_COMPAT_ENFORCE_REASONS,AXONFLOW_IDENTITY_COMPAT_AGREEMENT_LOG_EVERY,AXONFLOW_IDENTITY_COMPAT_PATHSAXONFLOW_DECISION_SHADOW_MODE,AXONFLOW_DECISION_SHADOW_PLANES,AXONFLOW_DECISION_SHADOW_SAMPLE_RATE,AXONFLOW_DECISION_SHADOW_QUEUE_DEPTH,AXONFLOW_DECISION_SHADOW_WORKERS,AXONFLOW_DECISION_SHADOW_MATCH_LOG_EVERY,AXONFLOW_DECISION_SHADOW_REALM,AXONFLOW_DECISION_SHADOW_CONTENT_TARGET
The per-organization settings are gone. The identity settings admin API no longer carries compat_mode, decision_shadow_mode or decision_shadow_planes, and a request that still sends one is refused 400, naming the field; see Identity Plane APIs.
Identity admission always runs
What enforce did on the identity axis in v10.x is part of every request in v11 on a deployment that verifies user identity; on Community and Community SaaS a presented user token is ignored and every request is decided for its client credential. Authentication runs first, as before: a bad credential, or a user token whose signature fails, is refused 401. Then the identity plane admits the request's subject:
- A user token must come from a declared trust realm. A token whose issuer no realm declares is refused
UNKNOWN_REALM, and so is a token with no issuer at all. In v10.x at the defaultoff, both were accepted. Tokens AxonFlow mints itself, through the portal or the API, carry an issuer the built-in realm declares and are unaffected. - The token's claims must bind. A token asserting an organization other than the credential's is refused
ORG_BINDING_MISMATCH; an expired, revoked or not-yet-valid token is refused with the matching reason; an upstream that asserts only an email address, and no stable subject, is refusedSUBJECT_MISSING. - An identity nobody could verify is not decided. When admission cannot reach an answer, for example because a realm's revocation source is unavailable, the request fails closed with
503 subject_unverifiablerather than being decided for an unverified identity. - A request with no user identity is decided for its client credential. Where a deployment can verify no per-user identity (Community, Community SaaS), or a request carries none (the OpenAI-compatible route), the authenticated credential is the principal, recorded as
subject_type: Client. A caller that sent a user token which failed is never admitted as its credential instead.
A refused admission is rendered by each plane in its own shape: a deny verdict on POST /api/v1/decide, and 403 on Gateway Mode's pre-check and on Proxy Mode's POST /api/request.
Before you upgrade
- Remove the variables listed above from every agent and orchestrator environment, and remove their CloudFormation parameters from your stack overrides:
DecisionShadowMode,DecisionShadowPlanes,DecisionShadowSampleRate,DecisionShadowQueueDepth,DecisionShadowWorkers,DecisionShadowMatchLogEvery,IdentityCompatMode,IdentityCompatEnforceReasons,IdentityCompatPathsandIdentityCompatAgreementLogEvery. - On Enterprise, declare a trust realm for every issuer of the user tokens your clients send, and make sure every token carries an issuer. This was the
UNKNOWN_REALMdivergence the v10.x shadow mode reported; in v11 it is a refusal. - Have a trusted-header upstream assert a stable subject (
X-User-ID), not only an email address. - Drop automation that writes
compat_mode,decision_shadow_modeordecision_shadow_planesthrough the identity settings API. - Retire dashboards and alerts built on the
[IDENTITY-COMPAT]log lines and the decision shadow counters: nothing emits them in v11.
Related
- Policy and Identity Control Plane: what decides a request in v11, and who it is decided for.
- v10 → v11 Migration Guide: everything that changes on upgrade.
- Identity Plane APIs: the Shared Signals receiver and the identity settings record.
- Per-Developer Identity: the per-user tokens a request carries.
- v10.2.0 release notes: what this switch did when it shipped.
