Parte II — Tronco e radici
05 · Il cerchio: identità e permessi
Ubuntu: "io sono perché noi siamo". In Baobáxia, chi sei vale in tutta la rete; cosa puoi fare vale dentro il cerchio che ti riconosce.
File da leggere
services/auth.py— password (PBKDF2), token JWT, verifica del token di un'altra mucua, freno dei tentativi.api/v3/auth.pyeapi/v3/deps.py— il login e come il token diventa ilmocche ogni rotta riceve.infra/identity.py— chiavi Ed25519 (firma) e X25519 (cifratura).services/permissions.py—can(): ogni decisione di accesso passa da qui.services/acesso_galaxia.py,services/grupos.py,services/acl.py.infra/envelope.py— cifratura end-to-end.services/challenge.py,services/recovery.py,infra/seed_phrase.py.
Due identità, una persona
- Password (
password_hashPBKDF2-SHA256, 200 mila iterazioni) nel saber della mocambola. - Chiavi: una coppia Ed25519 (firma paternità e token) + una coppia X25519 (apre saberes cifrati). La privata resta in
~/.baobaxia/keys/<uuid>.json, cifrata con la password (scrypt + AES-GCM), permessi 600 — non viaggia mai. La pubblica va nelsaber.bbx. BBX_AUTH_MODE=senha(password) |chave(chiave) |ambos(entrambi, il predefinito).
Login e token
sequenceDiagram
autonumber
actor P as Persona
participant A as POST /auth/login
participant F as freno (services/auth.py)
participant S as SaberService
participant K as identity
P->>A: username (o nome@uuid8 della mucua) + password
A->>F: tentativas_bloqueadas?
alt troppi errori nella finestra
A-->>P: 429
end
A->>S: find_mocambola (preferisce quella della mucua locale)
A->>A: verify_password (PBKDF2, compare_digest)
A->>K: cache_session_key — sblocca le private in memoria (8 h)
A->>A: _issue_for: ruolo effettivo + galassie amministrate
A->>K: firma un JWT EdDSA con la chiave della MUCUA (o HS256)
A-->>P: access_token (7 giorni) + profilo senza password_hash
Con il login tramite chiave: POST /auth/desafio restituisce un nonce monouso; POST /auth/login-chave invia la firma (e, se è una chiave secondaria, il certificato di delega firmato dalla principale).
Token firmato da un'altra mucua
flowchart TD
T[token EdDSA, iss = bbx:mucua:X] --> L{X è la mucua locale?}
L -- sì --> K[verifica con la chiave che sta SUL DISCO<br/>mai con la pubkey di un saber]
L -- no --> P[verifica con la pubkey del saber mucua X]
P --> Q{la mocambola sub è conosciuta qui?}
Q -- "sì, ed è di un'altra mucua" --> N[rifiuta: X risponde solo<br/>delle proprie mocambola]
Q -- "sì, ed è di X" --> R[ruolo, galassie e mucua<br/>ricalcolati con i NOSTRI dati]
Q -- no --> U[entra come USER, senza ambito]
La firma prova chi è; mai cosa può fare qui. (Questo disegno è della versione 3.3 — vedi il modulo 11.)
can(): la decisione
flowchart TD
A[can mocambola, azione, risorsa] --> S{attore di sistema?}
S -- sì --> OK[permette]
S -- no --> R{azione = READ?}
R -- sì --> RA{bozza?}
RA -- sì --> RB[solo autore, PAJÉ della mucua,<br/>OXALÁ della galassia]
RA -- no --> G{galassia riservata<br/>e fuori dalla lista?}
G -- sì --> NO[nega]
G -- no --> PR{protecao acl/cifrado?}
PR -- sì --> PL[lettori, autore;<br/>acl: + PAJÉ della mucua]
PR -- no --> V[visibility: public → tutti<br/>mucua → stessa mucua o OXALÁ<br/>private → proprietario o PAJÉ]
R -- no --> W{anonimo?}
W -- sì --> NO
W -- no --> RO{galassia in sola lettura?}
RO -- sì --> NO
RO -- no --> E[editor del saber UPDATE → gestore locale →<br/>proprietario → PAJÉ della mucua → OXALÁ della galassia]
Il descrittore della risorsa viene costruito in un solo posto (SaberService._descritor / _resource_of). Quando ogni rotta costruiva il proprio, alcune dimenticavano protecao e lasciavano trapelare dati — leggi il docstring di testes/test_vazamentos_de_leitura.py.
Cifratura end-to-end
Con protecao: cifrado, ogni saber riceve una chiave di contenuto (ChaCha20-Poly1305). description, body, location e gli allegati (.bbxenc) vengono cifrati; title e tags restano in chiaro per la ricerca. La chiave del saber viene avvolta per ogni lettore (X25519 ECDH + HKDF + AES-GCM). Il ruolo non apre la zucca: la apre solo chi ha un involucro con il proprio nome.
Recupero
Tre strade indipendenti (services/recovery.py): un guardiano autorizza la rotazione dell'identità (senza mai vedere password né contenuti), una frase seme costruita con risposte personali + entropia, oppure la chiave custodita nella mucua d'origine.
Esercizi
- In
test_token_federado_recalcula_papel.py, leggimucua_de_fora_nao_responde_por_mocambola_daqui. Spiega l'attacco con le tue parole. - Crea un saber con
protecao: acleleitores: [qualcuno]. Prova a leggerlo da anonimo tramite l'elenco, il dettaglio, la collezione, il download dell'allegato. (test_vazamentos_de_leitura.pyfa proprio questo.) - In
permissions.py, qual è la differenza traaclecifradoper un PAJÉ? Perché questa differenza è onesta?
Da discutere
- Il commento di
GalaxiaData.acesso(natures/schemas.py) chiama la galassia chiusa "cortesia del software". Cosa significa, e quando basta? - Chi dovrebbe essere guardiano dell'identità di qualcuno nella tua comunità?
