aeat.core.file_permissions module

Cross-platform best-effort file-permission hardening for auth state.

Both the FNMT-certificate-backed authenticator and the Cl@ve Móvil provider persist session-state JSON containing bearer-equivalent material (storage-state cookies, OAuth tokens, refresh tokens). The files must be restricted to the operator’s user account.

POSIX: chmod 0o600 is sufficient. Windows: icacls.exe /inheritance:r /grant:r <user>:(F) strips inherited ACLs and grants full control to the operator only. The icacls call is best-effort and tries both DOMAIN\\user and user candidate names so it works on standalone machines and domain-joined hosts.

The helper is shared between _authenticator and _clave_movil so the Windows-ACL discipline cannot diverge between the two session writers.

This module is a compatibility/public hardening primitive for plaintext files; the active AEAT browser-session persistence backend stores session state through secure objects. The Windows branch reads SYSTEMROOT and USERDOMAIN as OS ambient context only. It does not read AEAT-prefixed configuration or make permission tightening an authorization decision.

The public restrict_file_permissions() entry point accepts a Path target and deliberately returns None even when the best-effort hardening step cannot be applied.

See also

restrict_file_permissions()

Public entry point used by legacy/plaintext session writers.

_authenticator

FNMT-backed browser-session writer that shares this hardening helper.

_clave_movil

Cl@ve Móvil provider whose active session persistence now uses secure objects instead of plaintext storage-state files.

2026-06-05-secure-storage-production-hardening-w12-p26-s297-review-audit

Review that fixed silent POSIX failure swallowing and bounded ACL calls.

restrict_file_permissions(path)[source]

Best-effort restrict path to the operator’s user account.

POSIX: calls chmod() with mode 0o600.

Windows: shells out to icacls.exe to strip inherited ACLs and grant F (Full control) to the operator’s account only. Tries both DOMAIN\\user and bare user candidates because standalone machines have no USERDOMAIN and domain-joined machines may need the qualified form. The subprocess is time-bounded so a wedged icacls.exe cannot block the auth-state writer indefinitely. Logs at WARNING when every candidate fails — the file stays on disk with whatever ACL it inherited from its parent directory.

Best-effort: every error is swallowed so the auth flow never aborts on a hardening side-effect. Worst case is a slightly more permissive ACL than intended, surfaced via the warning log. Callers that need a confidentiality boundary should use the secure-object storage path rather than relying on this post-write permission adjustment.

Parameters:

path (Path) – Path to the file whose permissions must be tightened.

Return type:

None