Skip to content

feat(security): make the resolved permission posture explicit and observable - #231

Open
raymondginger2018-sudo wants to merge 3 commits into
HKUDS:mainfrom
raymondginger2018-sudo:security-posture
Open

feat(security): make the resolved permission posture explicit and observable#231
raymondginger2018-sudo wants to merge 3 commits into
HKUDS:mainfrom
raymondginger2018-sudo:security-posture

Conversation

@raymondginger2018-sudo

Copy link
Copy Markdown
Contributor

What

The effective permission posture is resolved from four interacting knobs — permission mode, access preset, command sandbox, approval policy — and no single one of them tells a reader whether a run was gated or wide open. An unattended full_auto run and an approval-gated one look identical in a transcript.

This makes the resolved posture explicit, visible, and tested:

  • core/harness/policy.pydescribe_security_posture(profile, *, sandbox_backend=None) returns a flat, string-friendly mapping (unattended being the headline fact) suitable for a log line or a structured event without further shaping. It reports facts; it does not judge them. Also states the module's public surface via __all__.
  • core/agent_setup.py — log the flattened posture once per session, next to the engine it describes, so "could a rewritten tool call have run unattended?" is answerable from the log instead of being reconstructed from four separate fields.
  • workflows/code_implementation_workflow.py — state default_mode=PermissionMode.FULL_AUTO at the call site: this workflow is the one caller that intentionally runs with no approver. No behaviour change; the intent is simply readable where it applies.
  • tests/test_harness_policy.py — 3 cases: the trap below, the gated modes, and rule counting.

The subtlety it encodes

Legacy full_auto short-circuits the engine with an unconditional ALLOW while still reporting an on_request approval policy. A report that trusted the policy field alone would therefore label the most permissive configuration as gated — the exact mistake this helper exists to prevent. That is why unattended is derived from both fields, and why the test asserts it.

Verification

  • pytest tests/test_harness_policy.py19 passed
  • pytest tests/test_harness_policy.py tests/application/test_agent_adapter.py tests/test_mcp_server.py tests/test_spawn_agent.py tests/test_subagent_composition.py75 passed
  • ruff check + ruff format --check on all four files with ruff 0.15.21 (the version pinned by .pre-commit-config.yaml) → clean
  • Pure addition: no behaviour change for existing callers.

The effective security posture is spread across four interacting knobs
(permission mode, access preset, command sandbox, approval policy), so no
single field in a transcript tells a reader whether the run was gated or wide
open: an unattended `full_auto` run and an attended one look identical.

`describe_security_posture(profile, *, sandbox_backend=None)` returns a flat,
string-friendly mapping suitable for a log line or a structured event, with
`unattended` as the headline fact. It reports facts; it does not judge them.

The one subtlety it encodes: legacy `full_auto` short-circuits the engine with
an unconditional ALLOW while still reporting `on_request`, so trusting the
approval policy field alone would label the most permissive configuration as
gated -- the exact mistake this helper exists to prevent.

Also exports the module's public names via `__all__` so the intended surface is
explicit. Pure addition; no behaviour change to existing callers.
`build_agent_session` resolves the security profile on every call, but the
result was invisible afterwards: the four knobs (permission mode, access
preset, command sandbox, approval policy) interact, so an unattended
`full_auto` run reads identically to an approval-gated one in a transcript.

Log the flattened posture once per session, next to the engine it describes,
so "could a rewritten tool call have run unattended?" is answerable from the
log rather than reconstructed from four separate fields.
This workflow is the one caller that intentionally runs with no approver.
Passing `default_mode=PermissionMode.FULL_AUTO` at the call site instead of
inheriting the signature default makes the intent readable where it applies,
and gives "who runs with no approver?" a grep-able answer. No behaviour change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant