Skip to content

Security blocker: FGAP Groups.manage permits group metadata changes #46

Open

Description

@Cenn0

Confirmed privilege boundary

The real Keycloak 26.8.1 integration test in PR #44 and CI #39119853859 demonstrated that the delegated service credential used to map application roles onto an approved group can also rename that group under its Groups.manage privilege. The synthetic name was restored after verification. This is an independently executed upstream permission-scope behavior, not an assertion that user-facing Permora API accepts group modifications.

Production risk

The current credential is not mapping-only. A compromised connector or token can exercise broader group administration even when Permora's typed API does not expose those operations. The core Keycloak 26.8.1 FGAP interface does not provide a verified Groups.map-role permission usable here; see upstream Keycloak issue #45269 (duplicate of #38806). Do not claim minimal mapping-only privilege or production acceptance.

Required engineering / release work

  • Add an explicit optional feature gate to disable delegated group-role mappings until deployment-specific IAM review authorizes this risk; preserve safe user mapping and revocations, and avoid blocking emergency group revoke operations. Implemented and merged in PR #47.
  • API-side direct HTTP negative test (403 without queue), exact Keycloak group ID opt-in, isolated connector grant-denial/revoke and read-back tests; PR #51 and CI #39397708574. Not a complete live-Keycloak end-to-end group revocation test of the disabled mode.
  • Probe same-scoped-service-token Keycloak 26.8.1 Admin REST blast radius: approved group rename is allowed; foreign group rename/delete and approved-group user membership mutations are denied; denied role mappings have no remote side effects. PR #55 on head 510d77d2a08316fea4476510c33dc8de54e6d50c; isolated live Keycloak CI passed.
  • Isolated real Keycloak + Portal API + worker + PostgreSQL + LDAPS disabled-group-grant/revoke path, both LDAP storage modes, HTTP 403/no queue, ambiguous-ID conflict/audit, owner retry, HTTP 503, actual committed group DELETE with reply loss/worker termination, postcondition recovery and unrelated-role read-back. PR #64, final PR head adf3f18206fd029df22f5cea3cd9f5af207f795d, system run #39934616783. Portal HTTP authentication is explicitly Development/loopback; genuine OIDC/MFA is tested separately.
  • Repeat and approve the disabled-grant/emergency-revoke path in the actual representative operator deployment, with verified IAM/network controls, secret rotation and external audit; the isolated fixture is not this acceptance.
  • Documentation added, operator verification outstanding: FGAP group acceptance and operational runbook details exact group allowlists, Keycloak Admin REST egress/network bypass, actual secret rotation, and external audit/alerting. No network/rotation/SIEM controls were automatically deployed by these changes.
  • Evaluate narrower delegation when officially supported upstream; version-gate a migration with positive/negative tests against future Keycloak versions.
  • Require signed central IAM risk approval or a demonstrated narrower entitlement before marking R03/R06 complete for production group mapping.

Acceptance: effective rights and out-of-scope Admin REST writes are probed with the same deployed service identity; no unsupported support claims. Reference: release checklist.

20 Oct 2026 evidence checkpoint

The direct Keycloak contract proved the privilege excess, not its removal. All 13 PR #55 checks succeeded; source merged as efa98973869a45f36b547cc3330b2e3eb1a07e7a. The issue remains open until a narrower vendor-supported effective entitlement or explicit deployment-specific central IAM risk acceptance and upstream/network controls are verified.

23 October 2026 — engineering path completed; production blocker remains

PR #64 merged as b7f5a30fe39c553e014d0d7152a1a5ddcbdd1648 after all seven exact-head PR workflows passed. Joined acceptance reports 115 assertions, 2 imported / 3 non-imported revocations, zero worker grant calls, real LDAP visibility loss with explicitly configured DirectoryProbeUserIds, duplicate source page and ambiguous persisted ID faults, Keycloak 503, remote commit/reply loss/crash and final restart/effective-role readback. New group grants stay disabled throughout. The optional visibility probe does not prove complete source/group visibility or freeze all realm operations. Shared worker test proxies now preserve chunked JSON role-list DELETE bodies, with an unrelated-role regression; the old proxy could otherwise broaden a test DELETE. Contract and limits.

Upstream was rechecked on 23 October: the latest release is still 26.8.1; #45269 is closed as duplicate and #38806 remains open. The live same-token contract still demonstrates the known group metadata privilege excess. No narrower supported effective entitlement has been demonstrated by this work.

Remaining blocker: actual deployed egress/bypass protection, service-profile scope and rotation/external audit evidence, and explicit central IAM risk acceptance (or a future verified narrower entitlement). This issue stays OPEN. Neither a normal merge nor a signed development draft is a production risk approval.

Post-merge verification: all six workflows on exact main b7f5a30fe39c553e014d0d7152a1a5ddcbdd1648 succeeded, including both joined LDAP modes and actual images, vulnerability gate and source/digest-verified draft signing. #58 is closed for the configured isolated engineering matrix. This security issue remains open for the deployment-specific risk and controls above.

Activity

  1. Cenn0 commented on Oct 18, 2026

    @Cenn0
    OwnerAuthor

    Engineering mitigation update — 18 Oct 2026 (issue remains OPEN)

    The following changes are implemented and merged into protected main:

    • PR #49: group grants default-denied at the API request boundary (HTTP 403 before queue/approval), and independently in the Keycloak worker connector; emergency revokes remain possible. API no longer receives worker Keycloak administrative credentials in the example deployment.
    • PR #50: manually initiated emergency revocations preempt older queued grants; queued revocation/backoff prevents further ordinary writes in that application. Real PostgreSQL regression tests exercise priority and stale-revision behavior.
    • PR #51: newly allowed group grants now require both per-realm opt-in and the exact Keycloak group ID in ApprovedGroupIds, checked separately in API and worker. Unknown or unlisted groups fail closed; safe revocations remain available. xUnit, simulated connector readback and real ASP.NET HTTP/PostgreSQL tests passed on the PR head. Merge SHA a6dc610719ac805f035311040062846bb7e3f2dc.

    This does NOT resolve the underlying Keycloak FGAP privilege breadth. A service token with Groups.manage may still modify group metadata or other fields even when Permora's typed API refuses to do so. Application-side allowlists are defense in depth, not a Keycloak mapping-only credential entitlement. Remaining production gates: same-identity upstream Admin REST negative probes across the full blast radius, deployment-specific IAM/egress restrictions, token rotation/audit monitoring, and signed central IAM risk acceptance or a tested narrower upstream Keycloak scope. Do not close this issue or approve production group grants on the strength of these merges alone.

  2. reopened this on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions