···7373```
74747575Also run `just smoke-permissioned` when touching `com.atproto.space.*`,
7676-permissioned-data storage, or the `/spaces` resident view.
7676+permissioned-data storage, or the `/account/spaces` resident view.
77777878Use `just invite` for admin-minted invite codes. Assume `ZDS_ADMIN_TOKEN` is
7979set in the repo `.env`; source it before running the target, for example
+4-3
README.md
···3333## docs
34343535- [architecture](docs/architecture.md)
3636-- [account security](docs/account-security.md)
3636+- [account management](docs/account-security.md)
3737- [comail](docs/comail.md)
3838- [development](docs/development.md)
3939- [operator guide](docs/operations.md)
···136136 Revocation also invalidates active sessions created with that app password.
137137- Passkeys are optional account credentials for the OAuth login page. ZDS stores
138138 credential IDs, public keys, counters, names, and last-use timestamps.
139139-- `/security` is the local account-security page for passkey and app-password
140140- management.
139139+- `/account` is the resident account hub. It includes passkey and app-password
140140+ management, app access/session views, email/account status controls, and the
141141+ experimental permissioned-space record browser.
141142- `com.atproto.space.*` permissioned-data routes are an experimental prototype
142143 and operator gated with `ZDS_PERMISSIONED_DATA`. ZDS implements enough storage
143144 and credential substrate for local experiments, but the upstream proposal is
+12-6
docs/account-security.md
···43434444## management UI
45454646-`/security` is the local account-security surface. It signs in with the account
4747-password, then lists passkeys and app passwords for that account. App passwords
4848-can be created and revoked from the page; the generated password is displayed
4949-once and is not recoverable later because only the hash is stored. The
5050-privileged-app-password checkbox is labeled as trusted-client behavior because
5151-ordinary clients should not request it casually.
4646+`/account` is the local resident account hub. Its security section,
4747+`/account/security`, signs in with the account password, then lists passkeys and
4848+app passwords for that account. App passwords can be created and revoked from
4949+the page; the generated password is displayed once and is not recoverable later
5050+because only the hash is stored. The privileged-app-password checkbox is labeled
5151+as trusted-client behavior because ordinary clients should not request it
5252+casually.
5353+5454+The same hub also exposes app/OAuth sessions, direct API token families,
5555+resident email and account-status controls, and the experimental
5656+permissioned-space record browser. `/security` and `/passkeys` remain
5757+compatibility redirects to `/account/security`.
52585359## references
5460
+4-4
docs/architecture.md
···8080login is supported so an account can be chosen by the authenticator during the
8181OAuth flow.
82828383-`/security` is the local management surface for passkeys and app passwords. It
8484-uses account-password authentication for management actions, matching the
8585-official PDS boundary that app passwords cannot mint or revoke other app
8686-passwords.
8383+`/account` is the resident management surface. Its security section,
8484+`/account/security`, manages passkeys and app passwords with account-password
8585+authentication, matching the official PDS boundary that app passwords cannot
8686+mint or revoke other app passwords.
87878888PDS-owned `app.bsky.actor` preferences are handled locally because the official
8989PDS implements those routes. Appview reads and writes remain behind the generic
+5-4
docs/operations.md
···202202203203## account security
204204205205-The local security surface lives at `/security`. It is for account-owner
206206-management of passkeys and app passwords and requires the account password for
207207-management actions. App-password revocation also revokes active sessions that
208208-were created with that app password.
205205+The resident account surface lives at `/account`. The security section,
206206+`/account/security`, is for account-owner management of passkeys and app
207207+passwords and requires the account password for management actions.
208208+App-password revocation also revokes active sessions that were created with
209209+that app password. `/security` and `/passkeys` are compatibility redirects.
209210210211## conformance
211212
+5-5
docs/passkeys.md
···2323If the login hint resolves to an account with saved passkeys, the OAuth page
2424offers passkey login first and keeps password login available. If no passkey is
2525saved for the account, password login is shown directly and points the user to
2626-`/security` after authentication.
2626+`/account/security` after authentication.
27272828Discoverable passkey login is supported: the browser may return a credential
2929without the page first choosing an account. ZDS resolves the credential ID to
···32323333## management
34343535-Passkeys are managed from `/security`, alongside app passwords. That page signs
3636-in with the account password, lists saved passkeys, and supports add, rename,
3737-and delete. Registration uses a browser WebAuthn prompt; ZDS stores only the
3838-credential ID, public key, counter, name, and timestamps.
3535+Passkeys are managed from `/account/security`, alongside app passwords. That
3636+page signs in with the account password, lists saved passkeys, and supports add,
3737+rename, and delete. Registration uses a browser WebAuthn prompt; ZDS stores only
3838+the credential ID, public key, counter, name, and timestamps.
39394040Deleting a passkey removes it from ZDS. The browser, OS, or password manager
4141may still keep its copy, but it can no longer be used with this PDS.
+2-2
docs/permissioned-data.md
···151151152152- HTTP dispatch and XRPC semantics live in `src/atproto/space.zig`.
153153- Experimental protocol helpers live in `src/internal/permissioned_data.zig`.
154154-- The resident private-record browser lives in
155155- `src/internal/private_spaces.zig`.
154154+- The resident private-record browser lives in the `/account/spaces` section
155155+ rendered by `src/internal/account.zig`.
156156- OAuth scope parsing for `space:` scopes lives in `src/internal/scopes.zig`.
157157- Persistent state lives in permissioned-data tables in
158158 `src/storage/store.zig`.
+1-1
src/atproto/oauth.zig
···301301 \\<button class="deny" name="deny" value="1" formnovalidate>deny</button>
302302 \\<button>authorize</button>
303303 \\</div>
304304- \\<p class="security-link">Want passkey sign-in next time? Add one from <a href="/security">security</a>.</p>
304304+ \\<p class="security-link">Want passkey sign-in next time? Add one from <a href="/account/security">account security</a>.</p>
305305 \\</div>
306306 );
307307}