Skip to content

Report permissions on project writes; throttle API-key last_used_at - #489

Merged
golharam merged 1 commit into
mainfrom
project-write-permissions-and-key-touch
Oct 30, 2026
Merged

golharam merged 1 commit into
mainfrom
project-write-permissions-and-key-touch

Conversation

@golharam

Copy link
Copy Markdown
Contributor

Two small, independent API fixes left over from the RBAC rollout.

1. PUT/PATCH /projects/{id} return the caller's permissions

The detail route reports what the caller may do in a project, but the write routes returned permissions: null, so a UI that saved a project had to re-read it to keep its controls right.

Both routes now fill the field through the same effective_project_permissions call as the detail route (_with_permissions in api/project/routes.py).

Restriction is read from the saved project, not from the project loaded before the write. A save can change restricted. An administrator who is not a member and locks a project can, from that point, only view it. The response then lists project:read, sample:read and project:manage_members, and no longer offers actions that would answer 403.

POST /projects is unchanged and still returns null; the list routes still leave it unset to avoid an N+1. The ProjectPublic comment and docs/RBAC.md are updated to match.

2. authenticate_api_key no longer writes on every request

Every API-key request set last_used_at and committed, so each call made a database write and commit, even a read. The column is now refreshed only when it is empty or older than API_KEY_TOUCH_INTERVAL (5 minutes).

Everything that reads it (idle-key review, list_service_accounts.py, create_service_account.py) works in days, so 5-minute precision loses nothing. The docs/RBAC.md item that flagged this is struck through.

Tests

  • test_rbac_admin.py:
    • PUT and PATCH return permissions.
    • A restricting write by a non-member superuser returns only the view permissions.
  • test_api_keys.py:
    • A key used within the interval is not rewritten.
    • A stale key is refreshed.
    • The existing "first use sets last_used_at" test still passes.

Full suite on a clean git archive extract: 1530 passed. flake8 clean.

🤖 Generated with Claude Code

PUT and PATCH /projects/{id} now carry the caller's `permissions`, as the
detail route does, so a UI that saves a project does not have to re-read it.
Restriction is read from the saved project, so locking a project you are not
a member of answers with only the view permissions.

authenticate_api_key refreshed last_used_at and committed on every request.
It now writes at most once per API_KEY_TOUCH_INTERVAL (5 minutes) per key;
the column feeds idle-key judgements made in days.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@golharam
golharam merged commit 9a4d92d into main Oct 30, 2026
5 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