Brings develop (policy format 1.1.0 with Deny, prefix wildcards, named permissions; PR 69, four independent fail-open reviews, Gitea CI green) into release/0.1. The committed revision is already 0.1.0-RC.10, so merging this publishes 0.1.0-RC.10.
Note for hosts: documents stored as 1.0.0 stop parsing (see UPGRADE.md); the typed PolicyResult API replaces the Set-returning fromClaims for session assembly.
Brings develop (policy format 1.1.0 with Deny, prefix wildcards, named permissions; PR 69, four independent fail-open reviews, Gitea CI green) into release/0.1. The committed revision is already 0.1.0-RC.10, so merging this publishes 0.1.0-RC.10.
Note for hosts: documents stored as 1.0.0 stop parsing (see UPGRADE.md); the typed PolicyResult API replaces the Set-returning fromClaims for session assembly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Spec and shared golden vectors only; no parser change yet.
- Effect Allow|Deny; result = union(Allow) minus union(Deny) across all of
a user's groups, Deny wins, no ordering, expanded against the live
instance so a Deny also covers future resources.
- Prefix resources (utils_*): at least two characters, literal part ends in
an underscore, wildcard last. Deny with Action * means every action
including features; Allow with Action * stays the five standard actions.
- Permission[] key for exact dotted/host permission names under Allow and
Deny, so Deny can remove what full access includes.
- Zero-match prefix, feature or named permission is rejected at save for
both effects. Unknown statement keys (Condition) reject the document.
- One invalid document among a user's groups voids all of them: dropping a
bad group could drop a Deny and escalate access.
- Canonicalization never drops a Deny.
- policy-vectors-1.1.0.json: 27 vectors over a 16-name universe, to be run
by this parser, the authentik-cd claim validator and Forge's tests.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Permission names are dot-separated segments of [A-Za-z0-9_-] (bare names
allowed); Resource stays [A-Za-z0-9_]+ and utils_* prefixes. Every Allow
expands against one universe, host names are not features, a standard action
a resource lacks is dropped, and the claim is one merged document.
New vectors: hyphenated and bare Permission names, invalid names, hyphenated
Resource, host name as Action, dropped action, not-in-universe name.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
PolicyParser returns typed PolicyRules (Allow and Deny terms, or void) instead
of permission names, so a Deny or prefix cannot be read as a grant. Result =
union(Allow) minus union(Deny) across all of a user's groups; one invalid
policy voids every group of the user. Allow expands against one live universe;
Deny is a predicate. Canonicalization never drops a Deny. Editor: save-time
zero-match checks, effective-permission subset rule, release of Deny on
removal, last-admin check. Host names register without an Authentik runtime;
PolicyCatalog is cached per QInstance. Default PolicyVersion is 1.1.0.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Deny of a prefix or named resource covers its dotted host names; empty
Resource/Action/Permission arrays reject; the blueprint voids on any document
under the attribute that is not exactly our spec (skipping other specs is an
opt-in) and on duplicate keys. Spec: what a Deny subtracts, void is not empty,
operators, host customizer API, blueprint known differences.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Operator credit never includes a name their own policies deny; the configured
policy attribute is reserved against attribute edits; un-voiding an invalid
policy is a release; a deliberate Deny no longer trips the cut-over guard and
void is shown; a group missing from the graph voids; PolicyResult typed API
with apply(); Deny of a prefix covers dotted host names; empty arrays and bad
host names reject; Save Policy requires expectedFingerprint; the catalog cache
key covers all rule sources and the runtime shares the cached catalog.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Documents with an unknown top-level key or no Statement are rejected (new
rawDocuments vectors); a Deny subtracts static and host floors, also while the
guard blocks; unreadable and void states; fingerprint covers the policy attribute.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The cut-over guard's blocked branch applies valid Deny rules (claim and graph) to
floor, host source and existing permissions; a guard error keeps the last known
state. Static and host floors are subject to Deny everywhere (bootstrap exempt),
including the refreshing mapper, which now reads Deny rules from the mirror
without an API call. PolicyResult gains UNAVAILABLE; a failed graph read with no
claim voids earlier permissions; resolveResult reports the full rules. Missing
parents void. Documents with unknown top-level keys or no Statement are
rejected. The group fingerprint covers the configured policy attribute. Stronger
tests for release, grandparent Deny, and the blueprint (fails without python).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
SessionPermissionRules.compute serves sign-in, automated sessions and the
refreshing mapper: void leaves break-glass only even while the guard blocks;
unavailable leaves only configured outage fallbacks; known applies every Deny to
policy grants, mirror permissions, static and host floors and earlier session
permissions. The refreshing mapper reads Deny rules from the mirrored group rows
on the same connection (checkpoint-consistent, bounded). Automated sessions void
on an unknown group pk and no longer keep earlier permissions when unresolved.
The guard keeps only a real last state (never OFF, original time, 15 min bound).
The mirror stores the policy document unredacted. Blueprint rejects extra
top-level keys and a missing Statement.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Bootstrap identity permissions are added to an operator after the Deny filter, so
a void or denying group cannot lock them out of repairing policies. A token with
no groups claim and no policy claim is unavailable (an empty array stays known).
The mirror restores a policy attribute verbatim only when it parses. Docs mark the
resolve/resolveResult/apply helpers as not for sign-in assembly. More mapper tests
(void claim alone, bootstrap under void, guard error at sign-in, specific
QAuthenticationException on refused mirror snapshots).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The shared CI runner image has no python3, so the 'fail without python' rule made
every build red at the unit stage. The python run now skips unless
BLUEPRINT_PYTHON_REQUIRED=true; a pure-Java test keeps the blueprint's safety
shape checked everywhere.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Brings develop (policy format 1.1.0 with Deny, prefix wildcards, named permissions; PR 69, four independent fail-open reviews, Gitea CI green) into release/0.1. The committed revision is already 0.1.0-RC.10, so merging this publishes 0.1.0-RC.10.
Note for hosts: documents stored as 1.0.0 stop parsing (see UPGRADE.md); the typed PolicyResult API replaces the Set-returning fromClaims for session assembly.
🤖 Generated with Claude Code