session.proto RawHistoryFolder
1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "google/protobuf/timestamp.proto";
8
9// SessionService manages the owner's browser sessions and passkeys. The
10// browser itself never calls it: it signs in by opening the link that
11// CreateLoginLink returns, or with a passkey on the web's sign-in page, and
12// signs out by posting to the web's logout route. Registering a passkey and
13// signing in with one are browser-only ceremonies and are not part of this
14// API.
15//
16// Every RPC is owner-only: it needs the root token, or a stored token that
17// holds every scope and is not restricted to repositories. Any other caller
18// gets permission_denied. Sessions do not go through this API: the Connect
19// API accepts bearer tokens only and ignores cookies.
20//
21// Servers that implement this service list "session" in
22// GetVersionResponse.features. They also list "passkeys" when passkeys are
23// available (they need an https public URL with a DNS host name); without it,
24// ListPasskeys and RemovePasskey fail with failed_precondition.
25service SessionService {
26 // CreateLoginLink creates a one-time link that signs the owner's browser
27 // in. The link is valid for a short time (about a minute), can be used
28 // once, and is kept in memory only: a server restart voids it. Opening it
29 // shows a confirmation page; only confirming it consumes the link and sets
30 // the session. Creating a new link does not void an earlier one. Fails with
31 // resource_exhausted when too many links are pending.
32 rpc CreateLoginLink(CreateLoginLinkRequest) returns (CreateLoginLinkResponse);
33 // SignOutEverywhere ends every browser session at once, including those on
34 // other devices. Pending login links are not affected. Tokens are not
35 // affected either: revoke them with TokenService.
36 rpc SignOutEverywhere(SignOutEverywhereRequest) returns (SignOutEverywhereResponse);
37 // ListPasskeys lists the owner's registered passkeys, oldest first. Fails
38 // with failed_precondition when the server has passkeys disabled.
39 rpc ListPasskeys(ListPasskeysRequest) returns (ListPasskeysResponse);
40 // RemovePasskey removes one passkey. It also signs out every browser
41 // session, on every device, like SignOutEverywhere. Fails with not_found
42 // for an unknown id, invalid_argument for an id that is not base64url, and
43 // failed_precondition when the server has passkeys disabled.
44 rpc RemovePasskey(RemovePasskeyRequest) returns (RemovePasskeyResponse);
45}
46
47// CreateLoginLinkRequest is empty.
48message CreateLoginLinkRequest {}
49
50// CreateLoginLinkResponse holds the link.
51message CreateLoginLinkResponse {
52 // Url is the absolute link to open in a browser, on the public URL of the
53 // server. It holds a secret: clients print it to the terminal and nowhere
54 // else, and never log it.
55 string url = 1;
56 // ExpiresAt is when the link stops working if it is not used.
57 google.protobuf.Timestamp expires_at = 2;
58}
59
60// SignOutEverywhereRequest is empty.
61message SignOutEverywhereRequest {}
62
63// SignOutEverywhereResponse is empty.
64message SignOutEverywhereResponse {}
65
66// Passkey is a WebAuthn credential that can sign the owner in. It never
67// carries key material.
68message Passkey {
69 // Id is the credential id, base64url without padding. Pass it to
70 // RemovePasskey.
71 string id = 1;
72 // Name is the label the owner gave the passkey when registering it.
73 string name = 2;
74 // CreatedAt is when the passkey was registered.
75 google.protobuf.Timestamp created_at = 3;
76 // LastUsedAt is when the passkey last signed the owner in. It is unset
77 // when the passkey was never used.
78 google.protobuf.Timestamp last_used_at = 4;
79 // Synced is true when the authenticator reports the credential as backed
80 // up (the backup state flag), for example a passkey synced by a platform or
81 // a password manager.
82 bool synced = 5;
83}
84
85// ListPasskeysRequest is empty.
86message ListPasskeysRequest {}
87
88// ListPasskeysResponse holds the passkeys.
89message ListPasskeysResponse {
90 // Passkeys are the registered passkeys, oldest first.
91 repeated Passkey passkeys = 1;
92}
93
94// RemovePasskeyRequest names the passkey to remove.
95message RemovePasskeyRequest {
96 // Id is the credential id from Passkey.id.
97 string id = 1;
98}
99
100// RemovePasskeyResponse is empty.
101message RemovePasskeyResponse {}