Skip to content

Audit Dragonfly RBAC enforcement across frontend, Auth0, and mainframe boundaries #154

@import-pandas-as-numpy

Description

@import-pandas-as-numpy

Issue Draft: Dragonfly RBAC Is Not Enforced Consistently Across Frontend, Auth0, and Mainframe

Summary

dragonfly-mainframe-frontend now gates UI access and frontend API routes on Auth0 permissions, but
dragonfly-mainframe still accepts any valid Auth0 token for the configured audience without
checking permissions, roles, grant type, or GitHub organization membership. This creates a
boundary failure: the frontend is RBAC-aware, while the backend remains authentication-only.

The current infrastructure/Auth0 documentation overstates the protection level by implying RBAC is
required end-to-end, even though the mainframe code does not enforce it. The same gap also affects
machine-to-machine traffic, because internal clients currently use Auth0 tokens without a distinct
service authorization model.

Severity

High

Impact

  • A valid Auth0 token for the Dragonfly audience can be used directly against dragonfly-mainframe
    even when the token carries no read:packages, queue:packages, or report:packages
    permissions.
  • A user outside the approved GitHub organization boundary may still be accepted by the backend if
    they can obtain a valid Auth0 token for the audience through another client or flow.
  • UI enforcement can be bypassed by calling the backend directly.
  • Internal service traffic and human traffic are currently conflated, which makes it difficult to
    harden interactive access without risking breakage for cluster-internal clients.

Scope

  • dragonfly-mainframe-frontend
  • dragonfly-mainframe
  • infrastructure Auth0 and deployment documentation
  • Internal clients currently talking to mainframe with Auth0 bearer tokens

Findings

1. Backend accepts authenticated tokens without checking permissions

Severity: High

Impact:

  • Human callers with valid audience tokens can bypass frontend-only permission checks.
  • Backend mutation endpoints can be invoked without queue:packages or report:packages.

Affected code:

Evidence:

  • validate_token() only distinguishes auth0 vs cf and returns authenticated identity data.
  • AuthenticationData captures issuer, subject, audience, timestamps, and grant type, but not
    permissions, scope, azp, or any role data.
  • Mainframe endpoints use Depends(validate_token) but do not apply any permission-specific
    authorization checks.

2. Frontend permission checks stop at the frontend boundary

Severity: High

Impact:

  • The frontend gives operators the appearance of RBAC enforcement, but that protection is lost once
    the backend is called directly.

Affected code:

Evidence:

  • The frontend reads permissions from the Auth0 access token and blocks UI/API actions when
    required permissions are missing.
  • The frontend forwards the same access token to mainframe.
  • Mainframe does not re-check those permissions.

3. Tenant docs claim RBAC protections the backend does not actually enforce

Severity: Medium

Impact:

  • Operators may believe enabling Auth0 RBAC and assigning roles is sufficient to protect the
    backend.
  • Verification steps can pass at the UI layer while the backend remains vulnerable to direct API
    access.

Affected code:

Evidence:

  • The docs require enabling Auth0 RBAC and adding permissions.
  • The docs state those settings are required because the frontend builds authorization state from
    token permissions and the backend validates the JWT audience.
  • The functional checklist asserts that users without queue:packages or report:packages
    receive permission failures, but there is no backend code that enforces that outcome for direct
    API calls.

4. Service traffic uses the same audience without a distinct machine authorization model

Severity: Medium

Impact:

  • Hardening interactive access is risky because internal service clients depend on the same backend
    and are not clearly separated by scope or endpoint class.
  • Current machine clients use password-based Auth0 token acquisition rather than a dedicated
    service-to-service model.

Affected code:

Evidence:

  • The documented Post-Login Action only applies to the frontend application.
  • The loader and bot acquire Auth0 access tokens using the password grant and call mainframe with
    bearer tokens.
  • There is no documented or enforced split between interactive permissions and service-only access.

Recommended Changes

  1. Treat backend authorization as mandatory, not optional UI behavior.
  2. Define separate authorization expectations for:
    • interactive human users
    • service principals inside the cluster
    • Cloudflare Access clients, if they remain supported
  3. Update infrastructure/Auth0 docs to reflect the current gap and the target enforcement model.
  4. Stop asserting that Auth0 RBAC alone protects mainframe until backend checks exist.
  5. Add a dedicated dragonfly-mainframe remediation issue for code changes.

Related backend issue draft:

Reproduction Notes

  1. Authenticate through the frontend and obtain a valid Auth0 access token for the Dragonfly
    audience.
  2. Remove the required permission assignment for the user, or use a token minted without
    queue:packages / report:packages.
  3. Call mainframe directly with Authorization: Bearer <token>.
  4. Observe that backend endpoints only require token validity, not the expected permission set.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions