Repository navigation
service-template-894: Add protected users.revoke capability - #72
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Card:
service-template-894— Add protected users.revoke capabilityBranch:
pipeline/service-template-894→mainWhat the card asks for
Goal
Give newly generated backend+Telegram-bot services a protected, typed
users.revoke(channel, external_id)capability so the orchestrator can end a temporary QA grant by making the same storedUser.statusgate inactive.Context
service-template-893is merged on the default tree29417d16043981de449bead3e7fb3953b7455ce3. It provides protectedPOST /users/grant, publicGET /users/access,User/UserChannel, andUser.statusas the sole Telegram admission gate.codegen-orchestrator-1232deliberately preserved its temporary QA environment-slot protocol because the template had no expiry/revoke semantic. Its durableTemporaryAccessGrantreconciler already owns TTL, retries, release of QA, and proof that access has been removed. A later codegen card will change that reconciler to call this capability; it must not invent a permanent QA grant or emulate expiry in the template.services/backend/src/app/grant_capability.py: one generated-secretUSERS_GRANT_CAPABILITYis presented only asX-Grant-Capability. It currently protects only/users/grantand must protect every privileged users write endpoint without exposing the header in OpenAPI or helper commands.template/shared/spec/models.yaml,template/services/backend/spec/users.yaml,src/app/repositories/user.py,src/controllers/users.py, generated seeds, migrations, backend tests, tg_bot admission tests, contract docs, and Copier coverage.Acceptance criteria
users.revoke(channel, external_id)contract and protectedPOST /users/revokeroute. It accepts an explicit identity shape, returns the existing typedUserAccessresult, and uses the same single generatedUSERS_GRANT_CAPABILITYheader contract as grant. The header/value remains absent from generated OpenAPI examples, user-facing commands, events, diagnostics, and logs.revokenever creates or activates an identity. For an existing identity it idempotently changes that identity'sUser.statustoinactiveand returns the resulting inactive access state; repeats return the same inactive state. An unknown identity fails closed without creating a row. A subsequentusers.grantreactivates it through the existing sole activation path.User.status: after a successful revoke, that Telegram identity is denied before any application handler; no expiry field, environment allow-list, owner literal, channel-specific fallback, or second admission gate is introduced.GET /users/accessremains the read-only resolution contract and does not accept or expose the capability.Out of scope
TemporaryAccessGrantmodel, scheduler/reconciler, deploy worker, QA handoff, or environment-slot cleanup. Those consume this merged capability in the next card.… (truncated; the full text is on the card)
What the worker reports
Delivered candidate
89436d602b322212387aa7fd4dbcc9192fbdb483(Add user revoke capability).UserRevoke, protectedPOST /users/revoke, generated protocol/router/OpenAPI/TypeScript artifacts, and idempotent no-create deactivation through the existingUser.statusgate. Grant remains the sole activation path.X-Grant-Capabilitymiddleware boundary to authenticate both privileged writes before handling invalid, duplicate, missing, wrong, or malformed headers./users/accessremains read-only and undocumented capability-free.make lint-template, spec validation, and framework mirror sync passed.python -m pytest tests/unit tests/tooling tests/copier -m not slow; 286 passed, 13 deselected, exit 0, 168.001s. Receiptstate/checks/broad-a00b157112b08b9b.json, content tree5a7046dc38a1b8119d28dcc39b011aa90517457b, imported from this workspace. This is worker-local evidence; dispatcher exact-SHA validation remains authoritative.Workspace is clean.
TASK.mdwas not modified or committed.Opened by the secretary CI gate so that the
pull_requestworkflow runs. Title and body are built from the card and the worker's done report.