Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

web-sign-in — Nasazené povrchy vědí, kdo se ptá, a poskytovatelé identity jsou data

Jeden kanonický druh poskytovatele identity v .ai/repo/identity/providers/ popisuje každého providera jako data: jeho vydavatele, jeho endpointy nebo discovery dokument, požadované scopes, claim nesoucí stabilní subjekt a názvy proměnných prostředí, ve kterých přicházejí jeho přihlašovací údaje. Jediný tok ve stylu OpenID Connect ve spustitelném souboru obslouží každého providera v tomto adresáři; Google a Facebook jsou dva objekty, ne dvě cesty v kódu. Relace jsou nesené cookie, podepsané, krátké a odvolatelné; identita se k požadavku připojí jednou, v routeru, a každý povrch (HTTP, Cockpit, OpenAPI, MCP) ji čte ze stejného místa. O tom, co smí anonymní čtenář, rozhoduje klasifikace efektů v registru schopností, ne seznam pro jednotlivé routy, a dokument OpenAPI i Cockpit toto rozhodnutí uvádějí, protože ho oba projektují z registru. Vyškrtnout providera znamená smazat jeden soubor a znovu vygenerovat.

PLÁNOVÁNO 0 z 8 úkolů hotovo

připraveno
1
blokováno
7
aktivní
0
verify
0
hotovo
0
zrušeno
0

Problém

Vše, co tento repozitář poskytuje, se poskytuje každému, kdo dosáhne na port. To bylo bezpečné, dokud server vázal loopback a jediným čtenářem byl člověk stojící před checkoutem, a přestane to být bezpečné ve chvíli, kdy milník nasazení postaví před stejný router veřejnou URL HTTPS: Cockpit, API, dokument OpenAPI a povrch MCP by byly čitelné každému, kdo hosta najde, a žádná měnící schopnost by nikdy nemohla být vystavena přes prohlížeč, protože by nebylo komu změnu přiřadit. Zřejmá náprava je špatná dvakrát. Ručně psaní klienti poskytovatelů pro Google a Facebook by byly dvě implementace jednoho toku a zkompilovaný seznam toho, kteří poskytovatelé existují, by vložil rozhodnutí o identitě do zdrojového kódu v Rustu, kde každé jiné rozhodnutí tohoto repozitáře je deklarativním objektem pod .ai/repo/. Očekává se, že sada poskytovatelů se změní — oba první dva mohou být vyškrtnuty a nahrazeny, jakmile se zná publikum — a změna takového druhu musí být úpravou jednoho objektu, nikoli releasem spustitelného souboru.

Výsledek

Jeden kanonický druh poskytovatele identity v .ai/repo/identity/providers/ popisuje každého providera jako data: jeho vydavatele, jeho endpointy nebo discovery dokument, požadované scopes, claim nesoucí stabilní subjekt a názvy proměnných prostředí, ve kterých přicházejí jeho přihlašovací údaje. Jediný tok ve stylu OpenID Connect ve spustitelném souboru obslouží každého providera v tomto adresáři; Google a Facebook jsou dva objekty, ne dvě cesty v kódu. Relace jsou nesené cookie, podepsané, krátké a odvolatelné; identita se k požadavku připojí jednou, v routeru, a každý povrch (HTTP, Cockpit, OpenAPI, MCP) ji čte ze stejného místa. O tom, co smí anonymní čtenář, rozhoduje klasifikace efektů v registru schopností, ne seznam pro jednotlivé routy, a dokument OpenAPI i Cockpit toto rozhodnutí uvádějí, protože ho oba projektují z registru. Vyškrtnout providera znamená smazat jeden soubor a znovu vygenerovat.

Aktuální stav

Neexistuje žádná autentizace jakéhokoli druhu: žádná relace, cookie, typ identity, přihlašovací route, práce s přihlašovacími údaji ani pojem volajícího nikde v apps/majordomus-cli/src/http. Soubor lease zaznamenává URL a server varuje, když se naváže na cokoli jiného než loopback. Milník nasazení (fly-deployment) uvádí jako mimo rozsah, že mutující operace nasazení nesmějí být vystaveny neautentizovanému HTTP ani prohlížeči, což je omezení, které tento milník odstraňuje.

Cílový stav

Čtenáři, který otevře veřejnou URL, se poskytují veřejné povrchy jen pro čtení tak, jak jsou dnes. Čtenář, který se přihlásí kterýmkoli poskytovatelem deklarovaným v .ai/repo/identity/providers/, dostane relaci, je jmenován v Cockpit a smí vyvolat schopnosti, které politika efektů přihlášenému čtenáři dovoluje vyvolat. Přidání třetího poskytovatele je jeden soubor YAML; odstranění prvních dvou je smazání dvou souborů; ani jedno není změna kódu a vygenerovaná dokumentace, nabídka přihlášení v Cockpit a bezpečnostní schéma OpenAPI vše vyplývá ze stejných objektů.

Rozsah

  • .ai/repo/identity
  • .ai/repo/adrs
  • .ai/repo/rules/project
  • .ai/repo/policy.yaml
  • apps/majordomus-cli/src/identity
  • apps/majordomus-cli/src/capability/builtin
  • apps/majordomus-cli/src/http
  • apps/majordomus-cli/src/cockpit
  • share/kinds.yaml
  • share/allow
  • share/schemas
  • dokumentace
  • web
  • test/cases
  • .github/workflows

Mimo rozsah

  • Databáze uživatelů, úložiště profilů nebo jakýkoli záznam o čtenáři nad rámec relace potřebné k odpovědi na další požadavek
  • Hesla, obnova hesla, ověření e-mailu nebo jakékoli přihlašovací údaje, které by tento repozitář musel sám ukládat
  • Kódová cesta, klientská knihovna nebo SDK specifické pro poskytovatele pro Google, Facebook nebo jakéhokoli nástupce
  • Autorizační role, skupiny nebo jazyk řízení přístupu nad rámec toho, co už rozhoduje klasifikace efektů registru schopností
  • Jakýkoli přihlašovací údaj, tajemství klienta nebo token commitnutý do repozitáře, zapsaný do generovaného artefaktu, vykreslený do webu nebo zalogovaný
  • Vystavení mutujících schopností přihlášenému čtenáři dříve, než klasifikace efektů řekne, které je vůbec bezpečné vystavit
  • Přihlášení k lokálnímu vývojovému serveru jako požadavek; loopback zůstává otevřený, takže stávající pracovní postup se nemění

Kritéria přijetí

  • Každý fakt o provideru — vydavatel, endpointy, scopes, subject claim, jména proměnných s přihlašovacími údaji, zobrazované jméno, pořadí — žije v jednom objektu pod .ai/repo/identity/providers/ a nikde jinde
  • Google a Facebook jsou každý jedním takovým objektem a spustitelný soubor neobsahuje žádný identifikátor, endpoint ani větev jmenující kteréhokoli z nich
  • Smazání objektu poskytovatele odstraní poskytovatele z nabídky přihlášení, z generované dokumentace, ze schématu zabezpečení OpenAPI i z Cockpitu, bez další úpravy
  • Tok ověřuje state a nonce, odmítá callback, jehož state nevydal, připíná relaci k vydavateli a subjektu a odmítá poskytovatele, jehož přihlašovací údaje chybí, místo aby spustil tok, který nemůže dokončit
  • Cookie relace je podepsané, HttpOnly, omezené SameSite, Secure, když se povrch poskytuje přes HTTPS, a vyprší; odhlášení ho odvolá na straně serveru, nejen smaže v prohlížeči
  • Identita se rozhodne jednou v routeru a každý povrch ji čte z tohoto jediného místa; žádný povrch nezpracovává cookie podruhé
  • Co smí anonymní čtenář dělat, se odvozuje z klasifikace efektů registru schopností, ne ze seznamu routes
  • Žádný tajný sentinel umístěný v proměnných prostředí s přihlašovacími údaji se neobjeví v žádné odpovědi, generovaném artefaktu, řádku logu, cache, výstupu webu ani příkladu OpenAPI
  • Dokumentace uvádí, jak poskytovatele přidat a jak odebrat, a obě tvrzení provádí test, nejsou jen napsána

Validace

  • bash test/run.sh
  • bin/majordomus doctor
  • cargo test --workspace --all-features
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • majordomus generate --check

Požadované důkazy

  • provider_objects_canonical
  • provider_removal_proved
  • flow_hardened
  • session_hardened
  • single_identity_resolution
  • effect_derived_exposure
  • no_secret_leakage
  • documented_and_tested

Rizika

  • Tok OpenID Connect napsaný dvakrát — jednou pro poskytovatele, který odpovídá standardu, a jednou pro toho, který ne — je selhání, kterému tento milník existuje zabránit. Endpointy Facebooku se od Googlových liší pravopisem, ne tvarem; cokoli, co se skutečně nedá vyjádřit jako data o jednom toku, je defekt ve schématu objektu poskytovatele a opravuje se tam.
  • Přístupové údaje jsou jedinou částí, která nemůže být daty v repozitáři. Objekty jmenují proměnné prostředí; hodnoty přicházejí z úložiště tajemství nasazení a nikdy se nečtou do žádné struktury, která se serializuje, cachuje nebo vykresluje.
  • Přihlášení zve k plíživému rozšiřování rozsahu směrem k účtům, profilům a rolím. Relace existuje, aby odpověděla na další požadavek, a nic víc; cokoli dalšího patří milníku, který pro to má důvod.
  • Množina poskytovatelů se očekává ke škrtání. Návrh, který činí přidání Googlu a Facebooku levným, ale odebrání drahým, selhal, i když funguje.

Úkoly

Každý z nich je prováděcí kontrakt s vlastními kritérii přijetí, validačním příkazem a požadovanými důkazy. Sloupec wave je vrstva grafu závislostí, v níž úkol leží.

issuestatusvlnazávisí nanázev
I1201 PŘIPRAVENO 0 — Poskytovatel identity je deklarativní objekt a Google a Facebook jsou dva z nich
I1202 BLOKOVÁNO 1 I1201 Jeden typovaný model providerů čte objekty a žádný kód nejmenuje providera
I1203 BLOKOVÁNO 2 I1202 Jeden flow obslouží každého providera a odmítne vše, co nezahájil
I1204 BLOKOVÁNO 3 I1203 Relace je podepsaná, krátká a z pohledu serveru odvolatelná
I1205 BLOKOVÁNO 4 I1204 Identita se řeší jednou, v routeru, a každý povrch ji odtud čte
I1206 BLOKOVÁNO 5 I1205 Co smí anonymní čtenář, se odvozuje z klasifikace efektů, ne ze seznamu
I1207 BLOKOVÁNO 4 I1204 Žádný credential se nedostane na žádný výstup a nepřátelská metadata providera se vykreslí bezpečně
I1208 BLOKOVÁNO 6 I1202, I1206 Přidat providera je jeden soubor, odebrat ho je jedno smazání a obojí se provádí, nejen popisuje

Graf

graf závislostí web-sign-inz .ai/repo/project
flowchart LR
    I1201["I1201<br/>An identity provider is a declarative object, and Google and Facebook are two of them"]:::ready
    I1202["I1202<br/>One typed provider model reads the objects, and no code names a provider"]:::blocked
    I1203["I1203<br/>One flow serves every provider, and it refuses everything it did not start"]:::blocked
    I1204["I1204<br/>The session is signed, short, and revocable from the server"]:::blocked
    I1205["I1205<br/>Identity is resolved once, in the router, and every surface reads it from there"]:::blocked
    I1206["I1206<br/>What an anonymous reader may do is derived from the effect classification, not from a list"]:::blocked
    I1207["I1207<br/>No credential reaches any output, and hostile provider metadata renders safely"]:::blocked
    I1208["I1208<br/>Adding a provider is one file, removing one is one deletion, and both are executed rather than described"]:::blocked
    I1201 --> I1202
    I1202 --> I1203
    I1202 --> I1208
    I1203 --> I1204
    I1204 --> I1205
    I1204 --> I1207
    I1205 --> I1206
    I1206 --> I1208
    classDef done stroke:#16a34a,fill:#dcfce7,color:#14532d,stroke-width:2px
    classDef active stroke:#2563eb,fill:#eff6ff,color:#1e3a8a,stroke-width:2px
    classDef verify stroke:#7c3aed,fill:#f5f3ff,color:#4c1d95,stroke-width:2px
    classDef ready stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
    classDef planned stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
    classDef blocked stroke:#b45309,fill:#fffbeb,color:#78350f,stroke-width:2px
    classDef cancelled stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2px
    classDef superseded stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2px

Kanonický záznam: .ai/repo/project/milestones/web-sign-in.yaml. Přečtěte ho zpět pomocí majordomus plan show web-sign-in.

Prohledává názvy a popisy všech stránek, které tento web publikuje.