aeat.adapters.outbound.aeat.auth._clave_permanente module

Cl@ve Permanente auth provider for AEAT Sede Electrónica.

Implements the AuthProvider protocol for the DNI/NIE + password Cl@ve Permanente flow against the live portal. Unlike Cl@ve Móvil, routine Cl@ve Permanente login for AEAT read paths is fully headless-automatable: the operator supplies a DNI/NIE and password, the provider submits AEAT’s auth-method selector page and the Cl@ve IdP login form, and no phone approval, push notification, or QR scan is required. AEAT’s SMS-OTP elevation only applies to account activation, password recovery, and “top-level services” (elevated write operations) — none of which this project’s permanently-read-only scope reaches.

The provider returns AeatSession and AeatLoginAssertion records with Cl@ve Permanente-specific detail payloads. Fresh logins persist ClavePermanenteSessionMetadata next to encrypted Playwright storage state; resume and diagnostic probes rebuild ClavePermanenteSessionDetail from that metadata without carrying credential material in the session record.

Design summary:

  • The provider opens a Playwright context and drives the selector page + Cl@ve IdP login form directly; there is no human-in-the-loop wait state to poll, so both fresh login and resume can run headlessly.

  • The persisted session stores Playwright state and provider metadata together in the encrypted session object, under a Cl@ve Permanente-namespaced logical storage key that keeps it distinct from certificate and Cl@ve Móvil sessions.

  • AEAT/Cl@ve IdP form selectors are the least stable part of this surface — they track the Cl@ve frontend rather than a published AEAT contract — and are declared centrally in AeatClavePermanenteSurface so a frontend change is a one-file update.

See also

ClavePermanenteSessionMetadata

Provider-owned encrypted persistence contract.

ClavePermanenteSessionDetail

Public session detail projected from persisted metadata.

clave_permanente_login_error()

Builder for operator-reportable live-flow failures.

class ClavePermanenteAuthProvider(settings, *, browser_session_factory=None, navigation_timeout_ms=30000)[source]

Bases: object

Cl@ve Permanente implementation of the AuthProvider protocol.

Constructed by select_provider() when kind == AuthProviderKind.CLAVE_PERMANENTE. Both fresh login and resume run headlessly: the DNI/NIE + password form requires no operator-mediated approval step for AEAT read paths.

Parameters:
kind: AuthProviderKind
async authenticate(*, browser_session=None, target_url=None)[source]

Run the Cl@ve Permanente login flow and return an AeatSession.

Attempts to resume a cached session first. Falls back to a fresh DNI/NIE + password form submission against the Cl@ve IdP. Fresh success writes ClavePermanenteSessionMetadata and returns a session whose provider detail is ClavePermanenteSessionDetail.

Return type:

AeatSession

Parameters:
async verify(session, *, target_url=None)[source]

Re-probe that session’s cookies still unlock a Sede page.

Explicit target_url probes go through AEAT’s selector dispatcher. When no explicit target is supplied and the session metadata has a concrete post-auth landing URL, the probe navigates there directly.

Return type:

AeatLoginAssertion

Returns:

An AeatLoginAssertion describing the probe outcome.

Parameters:
describe()[source]

Return an AuthProviderDescription.

A missing identity or missing password is an undeclared state (info), a malformed identity is a real configuration fault (warning), and a fully-configured provider is info with a headless-ready summary — Cl@ve Permanente never requires an operator-mediated completion step for read paths.

Return type:

AuthProviderDescription

async close()[source]

Tear down any retained BrowserContextLike and browser session.

Return type:

None