Skip to content

feat(access): loosen a built-in guard for a while or one session (2.148.0) - #201

Merged
drknowhow merged 1 commit into
mainfrom
feat/hub-builtin-leases
Sep 23, 2026
Merged

drknowhow merged 1 commit into
mainfrom
feat/hub-builtin-leases

Conversation

@drknowhow

Copy link
Copy Markdown
Owner

Stacked on #200. Loosen a built-in guard for a while, or for one agent session, without touching its permanent mode.

A lease sets one guard to confirm or allow for 60 s to 8 h. It covers every session or one, and every project or one. When it ends, the guard is back where it was and there is nothing to undo.

  • services/builtin_leases.py stores leases in ~/.c3/builtin_leases.json. They are two-key, like modes: a row counts only while the keyring holds the sha256 of that exact row, so a row that is forged, edited, or copied back after revoke is ignored.
  • access_guard.effective_builtin_modes() applies live leases on top of the standing modes. A lease never tightens. When no lease file exists, the hot path makes one extra is_file call and no keyring reads.
  • A per-session lease needs the evaluating process to know its session. access_guard.bind_session() handles that: the PreToolUse hook binds the payload's session_id, and the MCP server binds _grants.session_id() in _svc before every tool call. The Hub, CLI and mobile API bind nothing, so only all-session leases apply there.
  • POST /api/hub/access/builtin/lease mints a lease, and minting always needs the Desk token and the glob typed back. A lease that wouldn't loosen anything is a 400. POST …/lease/revoke needs no token. GET /api/hub/access/builtin now lists leases.
  • The Hub panel lists live leases with a countdown and Revoke.

Known limit: the MCP server's host session id is taken at boot, so after /clear a session lease no longer matches that server's calls. Hook-side enforcement uses the payload id and is unaffected.

Tests: tests/test_builtin_leases.py (14 cases: realm and session scoping, expiry, forged and edited rows, revoke-then-restore, never tightening, TTL bounds, no keyring reads without a file, routes). Full suite: 4595 passed, 7 skipped; ruff clean.

https://claude.ai/code/session_01F6QMHB2mkrDJiQWfC1g9wy

…48.0)

A lease sets one guard to confirm or allow for 60 s to 8 h, for every
session or one, in every project or one, without touching its permanent
mode. Rows in ~/.c3/builtin_leases.json count only while the keyring holds
the sha256 of the exact row, so forged or edited rows are ignored, and a
lease never tightens. The hook and MCP server bind their session id so a
per-session lease applies; minting needs the Desk token and the glob.
Tests: test_builtin_leases.py; full suite 4595 passed, 7 skipped.

Claude-Session: https://claude.ai/code/session_01F6QMHB2mkrDJiQWfC1g9wy
@drknowhow
drknowhow force-pushed the feat/hub-builtin-leases branch from c6cfe87 to d51c710 Compare September 23, 2026 22:52
@drknowhow
drknowhow changed the base branch from feat/hub-builtin-modes to main September 23, 2026 22:52
@drknowhow drknowhow closed this Sep 23, 2026
@drknowhow drknowhow reopened this Sep 23, 2026
@drknowhow
drknowhow merged commit ba2c1f2 into main Sep 23, 2026
23 of 24 checks passed
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