Temporary access
Grant access that ends on its own: expiring access rules and group memberships, requestable groups decided by approvers, and revoking a grant early.
Access that ends on its own: a rule with an expiry, a group membership with an expiry, and a request flow in which a user asks to join a group for a while and an approver decides. Together they cover the on-call window, the contractor’s week and the “let me into prod for an hour” without anyone having to remember to take the access away again.
Expiring rules
An access rule takes an optional
expiresAt. Past it the rule stops applying; it stays in the list,
marked expired, until someone extends or deletes it, so the record of
what was open is kept. A new expiry must be in the future; an expired
rule may still be edited as long as its expiry is kept, extended or
cleared.
slopscale access-rules create --name "Migration window" \
--src 2 --dst 3 --protocol tcp --ports 5432 --expires 48h
slopscale access-rules update -i 7 --name "Migration window" \
--src 2 --dst 3 --protocol tcp --ports 5432 --expires 2026-09-30T18:00:00Z
The console’s rule editor has an Expires field, and the rule list says when a rule expires or that it did.
Expiring memberships
A machine or user can be added to a group until a time. The membership counts until then and is deleted afterwards; the rest of the group is untouched. Adding the same member again for good makes the membership permanent; a group edit that keeps the member keeps its expiry.
slopscale groups add-node -i 4 --node 12 --expires 4h
slopscale groups add-user -i 4 --user 3 --expires 2026-09-12T09:00:00Z
The console’s Groups dialog on a machine or user has an Until field
for the groups being joined, and GET /api/v1/group/{id} lists the
temporary memberships under expiries.
Access requests
A group marked requestable takes requests from users. A signed-in user
asks to join it for a duration, between five minutes and thirty days,
for one of their machines or for every machine they own, with a reason.
An approver, anyone with the policy_file scope, approves the request
for the duration asked or another one, or denies it, with a note the
requester sees. Approval adds the membership with its expiry and
rebuilds the policy at once; nobody decides their own request. A pending
request can be withdrawn by its requester; a decided one stays on record
until an approver deletes it.
Requests need a user behind the credential: a console session, or an API key owned by a user. A member holds no admin scope and can still file and follow their own requests. The console shows them under My access, which every signed-in user has, and shows an approver the queue on the Requests page under Access controls, with the number pending next to it in the sidebar.
slopscale groups create --name "Prod" --requestable
slopscale access-requests create --group 4 --node 12 --duration 2h --reason "deploy"
slopscale access-requests list --status pending
slopscale access-requests approve -i 1 --duration 1h --note "one hour is enough"
slopscale access-requests deny -i 2 --note "ask the team lead first"
slopscale access-requests revoke -i 1 --note "incident over"
slopscale access-requests cancel -i 3
Through the API, GET /api/v1/access-request/options lists what the
caller may ask for, POST /api/v1/access-request files a request,
GET /api/v1/access-request lists them (every one for
policy_file:read, otherwise the caller’s own; ?mine=true and
?status=pending narrow), POST /api/v1/access-request/{id}/approve
and /deny decide, POST /api/v1/access-request/{id}/revoke ends a
grant early, and DELETE /api/v1/access-request/{id} withdraws or
deletes.
Ending a grant early
An approver does not have to wait for a grant to run out. Revoking it drops the membership the approval added, rebuilds the policy at once and marks the request revoked with who ended it, when and why; the approval’s own record stays, so the request still says who granted it. Only access that is in effect can be revoked, and an approver may revoke their own. Deleting a request whose access is in effect is refused: the row is what shows the membership, so revoke it first.
The membership only goes when the approval is what put it there. A member who was already in the group for good, or whose membership a later approval extended further, keeps what it had: revoking one request never takes away access another grant or an operator gave.
One member can hold several approvals for the same group at once, and they share a single membership that ends with the last of them. Revoking one of those does not empty the group: the membership falls back to the furthest approval still standing, and goes only when none is left. So revoking a long grant leaves a shorter one that has not run out alone, and the member keeps the group until that one ends.
Removing the membership by hand says the same thing on the request.
Taking a machine or user out of the group, in the console, the CLI or
the API, marks revoked every approval that was keeping it there, so the
request list and the group never disagree. That path is a membership
change rather than a decision, so it raises no accessRequestRevoked
event; the requester learns of it the next time they look.
slopscale access-requests revoke -i 1 --note "incident over"
In the console the row menu on a request in effect has Revoke access, and the In effect tab of the Requests page lists every grant that is running, with when each one ends.
When access ends
The server checks every minute for rules and memberships whose time has passed, deletes the memberships and rebuilds the policy without them and without the expired rules, so a grant ends within a minute of its time and the clients get a new map. A membership that ends is not a policy change to a webhook subscriber; the approval was. Postures with a schedule (see Device trust) are the other way to open access by the clock, for a window that repeats every week.
Events and audit
The webhook events accessRequestCreated, accessRequestApproved,
accessRequestDenied and accessRequestRevoked carry the requester, the
group, the machine, the duration, the reason, the note and, once
approved, the expiry, so a Slack channel can follow the queue. The audit
log records access_request.create, access_request.approve,
access_request.deny, access_request.revoke and
access_request.cancel, and the existing group.member.add and
access_rule.* actions carry the expiry.
An email endpoint sent to approvers reaches whoever may decide a
request without a recipient list to keep up to date; see
Webhooks. Subscribing one to
accessRequestCreated is what stops a request waiting until an approver
happens to open the page, and the Requests page offers to set it up in
a click while nothing does.