···14141515This software isn't an afterthought by a company with limited resources.
16161717-It is a superset of the reference PDS, including: passkeys and 2FA (WebAuthn/FIDO2, TOTP, backup codes, trusted devices), did:web support (PDS-hosted subdomains or bring-your-own), multi-channel communication (email, discord, telegram, signal) for verification and alerts, granular OAuth scopes with a consent UI showing human-readable descriptions, and a built-in web UI for account management, OAuth consent, repo browsing, and admin.
1717+It is a superset of the reference PDS, including: passkeys and 2FA (WebAuthn/FIDO2, TOTP, backup codes, trusted devices), did:web support (PDS-hosted subdomains or bring-your-own), multi-channel communication (email, discord, telegram, signal) for verification and alerts, granular OAuth scopes with a consent UI showing human-readable descriptions, app passwords with granular permissions (read-only, post-only, or custom scopes), and a built-in web UI for account management, OAuth consent, repo browsing, and admin.
18181919The PDS itself is a single small binary with no node/npm runtime. It does require postgres, valkey, and s3-compatible storage, which makes setup heavier than the reference PDS's sqlite. The tradeoff is that these are battle-tested pieces of infra that we already know how to scale, back up, and monitor.
2020···66666767## License
68686969-TBD
6969+AGPL-3.0-or-later. Documentation is CC BY-SA 4.0. See [LICENSE](LICENSE) for details.
7070+
+2-7
TODO.md
···2233## Active development
4455-### Frontend
66-So like... make the thing unique, make it cool.
77-88-- [ ] Frontpage that explains what this thing is
99-- [ ] Unique "brand" style both unauthed and authed
1010-- [ ] Better documentation on how to sub out the entire frontend for whatever the users want
1111-125### Delegated accounts
136Accounts controlled by other accounts rather than having their own password. When logging in as a delegated account, OAuth asks you to authenticate with a linked controller account. Uses OAuth scopes as the permission model.
147···9083Auth: ES256K + HS256 dual support, JTI-only token storage, refresh token family tracking, encrypted signing keys (AES-256-GCM), DPoP replay protection, constant-time comparisons.
91849285Passkeys and 2FA: WebAuthn/FIDO2 passkey registration and authentication, TOTP with QR setup, backup codes (hashed, one-time use), passkey-only account creation, trusted devices (remember this browser), re-auth for sensitive actions, rate-limited 2FA attempts, settings UI for managing all auth methods.
8686+8787+App password scopes: Granular permissions for app passwords using the same scope system as OAuth. Preset buttons for common use cases (full access, read-only, post-only), scope stored in session and preserved across token refresh, explicit RPC/repo/blob scope enforcement for restricted passwords.
···266266 "revokeConfirm": "Revoke app password \"{name}\"? Apps using this password will no longer be able to access your account.",
267267 "saveWarningTitle": "Important: Save this app password!",
268268 "saveWarningMessage": "This password is required to sign into apps that don't support passkeys or OAuth. You will only see it once.",
269269- "acknowledgeLabel": "I have saved my app password in a secure location"
269269+ "acknowledgeLabel": "I have saved my app password in a secure location",
270270+ "permissions": "Permissions",
271271+ "scopeFull": "Full Access",
272272+ "scopeReadOnly": "Read Only",
273273+ "scopePostOnly": "Post Only",
274274+ "scopeCustom": "Custom"
270275 },
271276 "sessions": {
272277 "title": "Active Sessions",
+6-1
frontend/src/locales/fi.json
···266266 "revokeConfirm": "Peruuta sovelluksen salasana \"{name}\"? Sovellukset, jotka käyttävät tätä salasanaa, eivät enää pääse tilillesi.",
267267 "saveWarningTitle": "Tärkeää: Tallenna tämä sovelluksen salasana!",
268268 "saveWarningMessage": "Tämä salasana tarvitaan kirjautumiseen sovelluksiin, jotka eivät tue pääsyavaimia tai OAuthia. Näet sen vain kerran.",
269269- "acknowledgeLabel": "Olen tallentanut sovelluksen salasanani turvalliseen paikkaan"
269269+ "acknowledgeLabel": "Olen tallentanut sovelluksen salasanani turvalliseen paikkaan",
270270+ "permissions": "Käyttöoikeudet",
271271+ "scopeFull": "Täydet oikeudet",
272272+ "scopeReadOnly": "Vain luku",
273273+ "scopePostOnly": "Vain julkaisut",
274274+ "scopeCustom": "Mukautettu"
270275 },
271276 "sessions": {
272277 "title": "Aktiiviset istunnot",
···266266 "revokeConfirm": "앱 비밀번호 \"{name}\"을(를) 취소하시겠습니까? 이 비밀번호를 사용하는 앱은 더 이상 계정에 액세스할 수 없습니다.",
267267 "saveWarningTitle": "중요: 이 앱 비밀번호를 저장하세요!",
268268 "saveWarningMessage": "이 비밀번호는 패스키 또는 OAuth를 지원하지 않는 앱에 로그인하는 데 필요합니다. 한 번만 볼 수 있습니다.",
269269- "acknowledgeLabel": "앱 비밀번호를 안전한 곳에 저장했습니다"
269269+ "acknowledgeLabel": "앱 비밀번호를 안전한 곳에 저장했습니다",
270270+ "permissions": "권한",
271271+ "scopeFull": "전체 권한",
272272+ "scopeReadOnly": "읽기 전용",
273273+ "scopePostOnly": "게시만 가능",
274274+ "scopeCustom": "사용자 지정"
270275 },
271276 "sessions": {
272277 "title": "활성 세션",
+6-1
frontend/src/locales/sv.json
···266266 "revokeConfirm": "Återkalla applösenord \"{name}\"? Appar som använder detta lösenord kommer inte längre att kunna komma åt ditt konto.",
267267 "saveWarningTitle": "Viktigt: Spara detta applösenord!",
268268 "saveWarningMessage": "Detta lösenord krävs för att logga in i appar som inte stöder passkeys eller OAuth. Du ser det bara en gång.",
269269- "acknowledgeLabel": "Jag har sparat mitt applösenord på en säker plats"
269269+ "acknowledgeLabel": "Jag har sparat mitt applösenord på en säker plats",
270270+ "permissions": "Behörigheter",
271271+ "scopeFull": "Full åtkomst",
272272+ "scopeReadOnly": "Endast läsning",
273273+ "scopePostOnly": "Endast publicering",
274274+ "scopeCustom": "Anpassad"
270275 },
271276 "sessions": {
272277 "title": "Aktiva sessioner",
···173173 <h3>You decide what apps can do</h3>
174174 <p>When an app asks for access, you'll see exactly what it wants in plain language. Grant what makes sense, deny what doesn't.</p>
175175 </div>
176176+177177+ <div class="feature">
178178+ <h3>App passwords with guardrails</h3>
179179+ <p>Create app passwords that can only do specific things: read-only for feed readers, post-only for bots. Full control over what each password can access.</p>
180180+ </div>
176181 </div>
177182178183 <h2>Everything in one place</h2>