Skip to content

Replace the hardcoded "admin" role literal with a named, configurable constant #222

@dgenio

Description

@dgenio

Summary

Centralize the "admin" role string — currently scattered across the kernel, dry-run,
and policy modules — into one named constant, and allow deployments to configure
which role unlocks raw response mode.

Why this matters

The admin gate decides who sees unredacted raw data — the most privileged path in the
system. A magic string repeated across kernel/_invoke.py, kernel/_dry_run.py, and
policy.py invites typo-class bugs (a misspelled role check fails open or closed
silently) and prevents organizations whose role taxonomy differs (e.g., superuser,
auditor) from adopting the gate cleanly.

Current evidence

  • kernel/_invoke.py:104: if response_mode == "raw" and "admin" not in principal.roles:
  • kernel/_dry_run.py:58: the same literal check duplicated.
  • policy.py:117: role doc/logic referencing "writer" / "admin" literals.
  • No constant in enums.py or models.py defines the privileged role.

External context

Not required for this issue.

Proposed implementation

  1. Add RAW_MODE_ROLE (or KernelConfig.raw_mode_role: str = "admin") in one place;
    replace all literals.
  2. Keep the default "admin" so behavior is unchanged.
  3. Ensure dry-run and real invoke read the same source (they must never disagree —
    dry-run's value is predicting the real outcome).
  4. Add a test that dry-run and invoke agree for a non-default configured role.

AI-agent execution notes

  • Inspect first: kernel/_invoke.py, kernel/_dry_run.py, policy.py, enums.py, tests/test_kernel.py.
  • Grep for every "admin" occurrence before claiming completion.
  • Edge cases: empty roles list; role configured to empty string (reject with typed error).
  • Do not change the downgrade-to-summary semantics.

Acceptance criteria

  • No raw "admin" literal remains in gate logic (constant or config only).
  • Default behavior is byte-for-byte unchanged.
  • A configured custom role gates raw mode in both invoke and dry-run (tested).

Test plan

Extend tests/test_kernel.py admin-gate tests with the configured-role case and a
dry-run/invoke agreement assertion. Run make ci.

Documentation plan

Document the role knob in docs/security.md (raw-mode section); CHANGELOG Added.

Migration and compatibility notes

Default unchanged; not expected to require migration.

Risks and tradeoffs

Configurability of a security gate must not become a foot-gun: validate the
configured role is non-empty and document that broadening it broadens raw access.

Suggested labels

architecture, security, good-first-ai-issue

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions