Skip to content

feat(charter-02): batch M1 — login end-to-end (GOA + PKCE loopback en daemon) [riesgo high, requiere ETH] - #73

Draft
montfort wants to merge 2 commits into
mainfrom
impl/charter-02-batch-m1-login-goa-pkce
Draft

feat(charter-02): batch M1 — login end-to-end (GOA + PKCE loopback en daemon) [riesgo high, requiere ETH]#73
montfort wants to merge 2 commits into
mainfrom
impl/charter-02-batch-m1-login-goa-pkce

Conversation

@montfort

@montfort montfort commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

DRAFT — NO MERGEAR todavía. Código de autenticación (risk_level: high).
Requiere aprobación humana del ETH ETH-2026-08-17-001 APROBADO
(2026-08-18, approved_by: montfort)
— resueltas sus 3 preguntas.
Pendiente: gate de capacidad del operador ejecutando el guion contra
OneDrive real.

CHARTER-02 · batch 1/M1 "Puedo entrar" — implementa el issue #70 (= FU-017).

Qué cambia

El login desde la app de preferencias pasa de "URL vacía rechazada por
Microsoft"
a dos rutas funcionales, con tokens SOLO en el keyring y
ningún secreto (tokens ni authorization code) cruzando D-Bus — extensión del
invariante RISK-002 al code.

Rutas (decisiones AIDEC-2026-07-04-001):

  • GOA (primaria en GNOME, D2): complete_auth_via_goa ahora enriquece
    best-effort vía Graph (prueba empírica del riesgo R1), persiste la cuenta y
    emite AuthStateChanged — antes no lo hacía.
  • Browser/PKCE (fallback universal): StartAuth arma el flujo real y una
    tarea de completion espera el redirect loopback dentro del daemon,
    valida CSRF, intercambia el code y persiste tokens + cuenta. Retirado
    Auth.CompleteAuth(code, state) — era el vector que llevaba el code por el bus.

FU-017 — consolidación:

  • redirect_uri unificado a http://127.0.0.1:8400/callback.
  • GraphCloudProvider::authenticate/refresh_tokens dejan de ser stubs
    bail!; componen GraphAuthAdapter detrás del puerto.
  • app_id origen flag > config > default; el CLI ya no falla duro sin config.

Señales desde segundo plano: ConnectionSlot publicado por
DbusService::start (re-publicado en cada reconnect del health-monitor,
RISK-001) + emit_auth_state_changed resuelve el InterfaceRef y emite.

Onboarding GNOME: botón para lanzar GNOME Online Accounts cuando no hay
cuenta lnxdrive_microsoft, con polling que lo sustituye por el botón GOA.

Meson: enable_goa default false -> true (proveedor host-side). El
Flatpak mantiene -Denable_goa=false a propósito (el proveedor debe cargarlo
el goa-daemon del host, no el sandbox).

Gobernanza

  • AILOG-2026-08-17-002 (draft, review_required, risk_level: high).
  • ETH-2026-08-17-001APROBADO (2026-08-18, approved_by: montfort).
    Resoluciones: ventana loopback 300 s se mantiene (CSRF+PKCE son el
    control); cuenta mínima GOA se mantiene (el sync usa /me/drive/*, no el
    drive id; expone R1 en vez de ocultarlo); peer-credentials D-Bus se difiere
    a v0.2 (DBus API lacks authentication and authorization #20 P2, DBus API rate limiting missing #22, ya en v0.2.0-beta).
  • straymark validate: 0 errores. followups drift: en sync.

Verificación

  • cargo test --workspace: 0 fallos (24 suites), incl. tests nuevos de
    armado/completion de flujo y URL PKCE real.
  • cargo clippy --workspace --all-targets -- -D warnings: limpio.
  • cargo build --features goa (preferences): OK.
  • meson setup intacto (aquí con -Denable_goa=false por ausencia de las
    libs de desarrollo GOA en este entorno).
  • Gate de capacidad PENDIENTE — el operador ejecuta el guion
    new-guide/09 §M1 contra OneDrive real (incluye gate R1). No se cierra M1
    contra mock (regla 1 del replanteo).

Checklist de merge

  • Revisión + aprobación humana del ETH-2026-08-17-001 (2026-08-18).
  • Operador instala el proveedor GOA host-side (meson install).
  • Operador ejecuta el guion M1 contra la cuenta de pruebas real.
  • Pasar el PR de draft a ready y mergear; luego straymark charter batch-complete CHARTER-02-road-to-functional-v0-1 1.

closes #70

…opback en el daemon)

Implementa el issue #70 (= FU-017): el login desde la app de preferencias
pasa de "URL vacía rechazada por Microsoft" a dos rutas funcionales, con
tokens SOLO en el keyring y ningún secreto (tokens ni authorization code)
cruzando D-Bus — extensión del invariante RISK-002 al code.

Rutas (decisiones AIDEC-2026-07-04-001):
- GOA (primaria en GNOME, D2): complete_auth_via_goa ahora enriquece
  best-effort vía Graph (prueba empírica del riesgo R1), persiste la cuenta
  y emite AuthStateChanged — antes no lo hacía.
- Browser/PKCE (fallback universal): StartAuth arma el flujo real y una
  tarea de completion espera el redirect loopback DENTRO del daemon,
  valida CSRF, intercambia el code y persiste tokens + cuenta. Retirado
  Auth.CompleteAuth(code, state) — era el vector que llevaba el code por el
  bus.

FU-017 — consolidación:
- redirect_uri unificado a http://127.0.0.1:8400/callback (fuente de verdad
  lnxdrive-graph::auth::REDIRECT_URI; DEFAULT_REDIRECT_URI de core alineado).
- GraphCloudProvider::authenticate/refresh_tokens ya no son stubs bail!;
  componen GraphAuthAdapter detrás del puerto (AuthenticateUseCase::login
  funciona end-to-end).
- app_id origen flag > config > default (DEFAULT_APP_ID pub); el CLI ya no
  falla duro sin config.

Señales desde segundo plano: ConnectionSlot publicado por DbusService::start
(re-publicado en cada reconnect del health-monitor, RISK-001) +
emit_auth_state_changed resuelve el InterfaceRef y emite.

Onboarding GNOME: botón "Add a Microsoft account in GNOME Online Accounts…"
cuando no hay cuenta lnxdrive_microsoft; abre gnome-control-center y un
polling lo sustituye por el botón GOA al existir la cuenta.

Meson: enable_goa default false -> true (proveedor host-side). El Flatpak
mantiene -Denable_goa=false a propósito (el proveedor debe cargarlo el
goa-daemon del host, no el sandbox).

Gobernanza (código de autenticación => risk_level high):
- AILOG-2026-08-17-002 (draft, review_required).
- ETH-2026-08-17-001 (draft) — el PR NO debe mergear sin aprobación humana
  del ETH según AGENT-RULES.md.
- straymark validate 0 errores; followups drift en sync.

Verification:
- cargo test --workspace: 0 fallos (24 suites), incl. tests nuevos de
  armad/completion de flujo y URL PKCE real.
- cargo clippy --workspace --all-targets -- -D warnings: limpio.
- cargo build --features goa (preferences): OK.
- meson setup intacto (aquí con -Denable_goa=false por ausencia de las libs
  de desarrollo GOA en este entorno).
- Gate de capacidad PENDIENTE: el operador debe ejecutar el guion
  new-guide/09 §M1 contra OneDrive real (incluye gate R1). No se cierra M1
  contra mock (regla 1 del replanteo).
… preguntas

El operador humano reviso y aprobo el ETH del batch M1 (approved_by:
montfort, 2026-08-18). Las tres preguntas abiertas quedan resueltas en el
documento:

1. Ventana del loopback: mantener 300 s — el control de seguridad son el
   state CSRF + PKCE, no la duracion de la ventana (el code inyectable no
   es fabricable; lo peor alcanzable es un DoS local del login).
2. Cuenta minima en fallo de Graph: mantenerla — el sync usa /me/drive/*
   y no depende del drive id; persistir expone el fallo real de scopes
   (R1) en vez de ocultarlo tras un daemon esperando en silencio.
3. Peer-credentials D-Bus: diferir a v0.2 — alineado con #20 (P2) y #22,
   ya milestonados a v0.2.0-beta; filtro por UID es un no-op en daemon de
   sesion, y los vectores de tokens/code ya estan cerrados.

AILOG-2026-08-17-002: nota actualizada — gate del ETH levantado; el merge
sigue pendiente del gate de capacidad del operador (guion M1 contra
OneDrive real).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M1: end-to-end login from preferences (GOA primary + browser/PKCE fallback)

1 participant