feat(be): let an app sign its own session out - #4245
Open
sea-snake wants to merge 103 commits into
Open
Conversation
|
✅ No security or compliance issues detected. Reviewed everything up to 0b155a4. Security Overview
Detected Code Changes
|
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 01:48
0c075d2 to
9ce7a2c
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 02:57
9ce7a2c to
354343e
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 03:47
354343e to
a650a94
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 06:28
a650a94 to
2b70415
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 07:07
2b70415 to
678bf30
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 08:17
678bf30 to
783da5a
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 08:37
783da5a to
69ab376
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 19, 2026 10:21
69ab376 to
4919341
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 20, 2026 10:57
4919341 to
1b98bba
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 20, 2026 13:08
1b98bba to
b943144
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 20, 2026 13:52
b943144 to
418c0f2
Compare
sea-snake
force-pushed
the
feat/app-revoke-session
branch
from
August 20, 2026 15:24
418c0f2 to
6aea53c
Compare
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ # Conflicts: # src/internet_identity/src/storage/tests.rs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ # Conflicts: # src/internet_identity/tests/integration/sessions.rs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
The expiry check stays in the delegation path, where this branch moved it: a session past its bounds is still the caller's to sign out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
# Conflicts: # src/internet_identity/src/sessions.rs
`app_revoke_session` was the odd one of its three siblings: no error channel, so
`.expect` caught only the `Err` and `Ok(false)` reported a successful sign-out
for a session left active. It returns `variant { Ok; Err : AppSessionError }`
now, like `app_prepare_delegation` and `app_get_delegation`, and the trap has no
job left. A session that is not there is still `Ok` — the caller wanted it gone
and it is gone, and they cannot tell a pruned session from one that never
existed.
`revoke_session` walked the list twice, once to check the session was there and
once to remove it, only so it could answer `Ok(false)`. With the not-found error
one `retain` does both.
`match_session` becomes `find_caller_session`: one finds the caller's session,
the other authorizes it, and the return types say so. The comment above the
sign-out now gives the narrower reason the two differ — not that an absent
session needs revoking, but that a present-and-expired one must not be refused.
Which nothing tested, so it does now.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVi99RYo2jyi2kCurgovNJ
# Conflicts: # src/internet_identity/src/sessions.rs
sea-snake
removed this pull request from stack #4276
September 9, 2026 20:34
sea-snake
added this pull request to stack #4323
September 9, 2026 20:34
sea-snake
removed this pull request from stack #4323
September 9, 2026 20:42
sea-snake
added this pull request to stack #4325
September 9, 2026 20:43
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.
Design: #4224. Overview: #4230.
Signing out of an app cleared browser state and invalidated nothing already issued.
app_revoke_session : () -> (variant { Ok; Err : AppSessionError })removes the session record, so the app's access ends within one delegation lifetime instead of running to the original expiry.Ok, so sign-out is idempotent: a client that retries, or signs out twice, gets the same answer without reasoning about whether its session was still there. Only a storage failure comes back as an error — the same error type its two siblings already return, so this is consistency with its own family rather than a new convention.The app deliberately cannot revoke anything else. "Sign out everywhere" is the II frontend's operation (#4246), not something a dapp can trigger.
Revocation latency is exactly the app-delegation TTL, by construction: revoking stops new mints and one already issued runs out.
mcp.rsdocuments the same residue for its grants.Tests:
session_removal_tests(3) plus PocketIC coverage that a refresh working before sign-out returnsNoMatchingSessionafter, three sign-outs in a list all succeed, an expired session is still signed out and its record and index entry go with it, and signing one browser out leaves another browser's session on the same account working.