# Piano tecnico API keys self-service su `admin_users`

## Obiettivo

Preparare un layer API per Legal Logger, basato su Laravel 10 e `z-song/laravel-admin`, con queste regole:

- nessun login dedicato per i client API;
- autenticazione solo tramite header `Authorization: Bearer <token>`;
- ogni utente del software autenticato nel pannello admin puo` creare e revocare le proprie API key;
- le funzionalita` API verranno aggiunte dopo, partendo prima dalla gestione sicura delle chiavi.

## Stato attuale del progetto

- Il backoffice usa `z-song/laravel-admin` con guard `admin` configurato in [`config/admin.php`](/var/www/llg/config/admin.php).
- Il model admin attuale e` il vendor model `Encore\Admin\Auth\Database\Administrator`.
- Sanctum e` gia` installato.
- La tabella [`personal_access_tokens`](/var/www/llg/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php) e` gia` presente.
- Le route API esistono gia` in [`routes/api.php`](/var/www/llg/routes/api.php), ma oggi c'e` solo l'endpoint demo `/user`.
- Il contesto applicativo sembra ruotare attorno a `admin_users` e a campi come `license_code`, `msp_code`, `customer_code`.

## Vincoli di progetto

1. Nessuna regressione sul login web del pannello admin.
2. Nessun riuso del login web come autenticazione per client API esterni.
3. Le API key devono appartenere al singolo record di `admin_users`.
4. Ogni utente deve poter gestire solo le proprie chiavi.
5. Il token in chiaro deve poter essere mostrato e copiato anche successivamente dal proprietario.
6. La futura esposizione dati API dovra` sempre rispettare il perimetro dell'utente autenticato.

## Scelta architetturale consigliata

### Principio

Separare nettamente:

- autenticazione web admin attuale;
- autenticazione API Bearer tramite Sanctum.

La parte web continua a funzionare come oggi. Le API useranno token personali associati agli utenti admin.

### Model dedicato alle API

Scelta consigliata per la prima implementazione:

- introdurre un model dedicato, ad esempio `App\Models\AdminApiUser`;
- farlo estendere da `Encore\Admin\Auth\Database\Administrator`;
- aggiungere `Laravel\Sanctum\HasApiTokens`;
- lasciarlo puntare alla tabella `admin_users`.

Motivo:

- evita di toccare il model vendor oggi usato dal pannello;
- isola il supporto Sanctum nel layer API;
- riduce il rischio in una codebase legacy.

Nota:

- in alternativa si potrebbe sostituire il model admin con un model locale che estende `Administrator` e usa `HasApiTokens`;
- non e` la prima scelta, perche' impatta direttamente la configurazione auth del backoffice.

### Guard API

Per gli endpoint protetti, il piano prevede di usare Sanctum con middleware `auth:sanctum` sulle route API versionate.

Per chiarezza progettuale, conviene comunque verificare in implementazione se serva anche un provider dedicato in [`config/auth.php`](/var/www/llg/config/auth.php) per i casi in cui il progetto voglia distinguere esplicitamente i consumer API dagli altri user provider.

## Cosa deve poter fare l'utente

Ogni utente autenticato nel pannello admin deve poter:

- vedere la lista delle proprie API key;
- creare una nuova API key personale;
- copiare il token in chiaro dopo la creazione;
- mostrare e copiare di nuovo una API key gia` esistente;
- revocare una propria API key;
- vedere metadati come nome, data creazione, ultimo utilizzo e scadenza.

Ogni utente non deve poter:

- vedere le chiavi di altri utenti;
- creare chiavi per conto di altri utenti;
- allargare il perimetro dati tramite parametri API.

## UI admin da prevedere

### Nuova sezione dedicata

Aggiungere una sezione admin dedicata, ad esempio:

- route admin: `/api-keys`
- controller dedicato: [`app/Admin/Controllers/ApiKeysController.php`](/var/www/llg/app/Admin/Controllers/ApiKeysController.php)

### Vista elenco

Contenuti minimi:

- nome token;
- `last_used_at`;
- `created_at`;
- `expires_at`;
- stato logico: attivo, scaduto, revocato;
- azione "mostra / copia";
- azione di revoca.

L'elenco deve mostrare solo i token dell'utente admin corrente.

### Creazione token

Campi consigliati:

- nome chiave obbligatorio;
- scadenza opzionale.

Output:

- il token in chiaro viene mostrato subito dopo la creazione;
- il token resta recuperabile dal proprietario anche in seguito.

### Persistenza del token in chiaro

Per supportare la copia successiva, il piano deve prevedere una persistenza aggiuntiva del token in forma cifrata.

Scelta:

- salvare una copia cifrata del token in chiaro nella tabella `personal_access_tokens`;
- usare la cifratura applicativa Laravel basata su `APP_KEY`;
- mostrare il token solo al proprietario della chiave.

Conseguenza:

- Sanctum continua a usare l'hash per autenticare il Bearer token;
- l'applicazione mantiene anche una copia cifrata del token per la funzione "mostra / copia".

## Portata delle API key

Per questa installazione non servono capabilities, scope applicativi o permessi per-endpoint sul token.

Ogni API key valida deve:

- autenticare l'utente che l'ha creata;
- avere accesso a tutte le API disponibili per quell'utente;
- ereditare integralmente il perimetro dati dell'utente autenticato.

Questo significa che il controllo di sicurezza non si basa su permessi associati al token, ma solo su:

- validita` del token;
- utente proprietario del token;
- perimetro dati derivato dall'utente, ad esempio `license_code`;
- eventuali regole applicative generali decise a livello endpoint.

Conseguenza pratica:

- in creazione token non serve selezione abilities;
- negli endpoint API non serve middleware `tokenCan()`;
- la sicurezza dipende dal corretto scoping dei dati per utente.

## Flusso utente previsto

1. L'utente fa login nel pannello admin con il flusso esistente.
2. Accede alla pagina "API Keys".
3. Inserisce nome ed eventuale scadenza.
4. Il sistema recupera il corrispondente record `AdminApiUser` a partire dall'utente admin loggato.
5. Il sistema genera il token con Sanctum.
6. Il sistema salva anche una copia cifrata del token in chiaro.
7. Il token in chiaro viene mostrato all'utente.
8. I successivi client API useranno solo `Authorization: Bearer <token>`.

### Flusso di copia successiva

1. L'utente apre la pagina "API Keys".
2. Seleziona una propria chiave esistente.
3. Il sistema recupera il record token del proprietario.
4. Il valore cifrato viene decifrato lato server.
5. Il token in chiaro viene mostrato di nuovo nella UI per la copia.

## Perimetro dati futuro

Quando inizieremo a pubblicare endpoint API, il perimetro dovra` essere derivato dall'utente autenticato e non dalla richiesta del client.

Nel progetto attuale, il primo candidato naturale per lo scoping e` `license_code`.

Quindi il piano API deve assumere fin da ora che:

- il token identifica un utente preciso di `admin_users`;
- ogni query API verra` filtrata sul contesto utente;
- parametri come `license_code` non potranno essere usati per espandere il perimetro.

## File coinvolti nella futura implementazione

### Configurazione

- [`config/auth.php`](/var/www/llg/config/auth.php)
- eventualmente [`config/admin.php`](/var/www/llg/config/admin.php) solo se emergera` la necessita` di un model locale anche per l'admin

### Model

- [`app/Models/AdminApiUser.php`](/var/www/llg/app/Models/AdminApiUser.php)

### Admin UI

- [`app/Admin/Controllers/ApiKeysController.php`](/var/www/llg/app/Admin/Controllers/ApiKeysController.php)
- [`app/Admin/routes.php`](/var/www/llg/app/Admin/routes.php)
- [`resources/views/admin/api-keys.blade.php`](/var/www/llg/resources/views/admin/api-keys.blade.php)

### Database

- migrazione aggiuntiva su `personal_access_tokens` per il campo cifrato del token in chiaro

### API

- [`routes/api.php`](/var/www/llg/routes/api.php)
- controller API versionati in `app/Http/Controllers/Api/V1/`
- eventuali request in `app/Http/Requests/Api/V1/`
- eventuali resource in `app/Http/Resources/Api/V1/`

### Test

- test feature in `tests/Feature/Api/`
- eventuali test sul backoffice per la gestione chiavi

## Piano operativo

### Fase 1

Preparare la base per le chiavi personali:

- introdurre il model API dedicato compatibile con Sanctum;
- creare la sezione admin "API Keys";
- mostrare elenco proprie chiavi;
- creare nuova chiave;
- permettere la riapertura e copia di una chiave esistente;
- revocare chiave;
- aggiungere test minimi sulla creazione e revoca.

### Fase 2

Attivare l'autenticazione Bearer vera e propria sulle API:

- versionare le route come `/api/v1/...`;
- proteggere gli endpoint con Sanctum;
- aggiungere un endpoint iniziale `GET /api/v1/me`;
- validare che il token identifichi correttamente l'utente `admin_users`.

### Fase 3

Esporre i primi dati applicativi:

- scegliere il primo dominio da pubblicare;
- applicare scoping su `license_code`;
- aggiungere test `401`, `403` e tenant isolation.

## Test da prevedere

### Gestione chiavi

- un utente vede solo le proprie chiavi;
- un utente puo` creare una propria chiave;
- il token in chiaro compare alla creazione;
- un utente puo` mostrare di nuovo una propria chiave esistente;
- un utente puo` revocare solo una propria chiave;
- un utente non puo` revocare la chiave di un altro utente.

### Sicurezza della copia successiva

- la copia successiva funziona solo per il proprietario della chiave;
- il token in chiaro e` salvato cifrato, non in plain text puro;
- la protezione effettiva dipende anche dalla sicurezza di `APP_KEY`.

### Auth API

- richiesta senza Bearer token restituisce `401`;
- token invalido restituisce `401`;
- token revocato restituisce `401`;
- token scaduto restituisce `401`.

### Scoping futuro

- utente con `license_code` A non vede dati della licenza B;
- i filtri client non possono allargare il tenant scope.

## Decisioni aperte prima dell'implementazione

1. Se imporre o no una scadenza obbligatoria ai token.
2. Se mettere un limite massimo di token per utente.
3. Se aggiungere audit esplicito sulla creazione e revoca chiavi.
4. Quale sara` il primo endpoint dati dopo `GET /api/v1/me`.

## Raccomandazione finale

La soluzione adottata e coerente con questa installazione e`:

- non toccare per ora il login admin esistente;
- usare Sanctum solo per il layer API;
- associare i token agli utenti di `admin_users`;
- permettere a ogni utente admin di creare, rivedere e revocare solo le proprie chiavi;
- introdurre gli endpoint API veri e propri solo dopo aver chiuso bene il flusso di gestione chiavi.

Questo approccio resta compatibile con l'architettura attuale, ma introduce un tradeoff esplicito:

- maggiore praticita` operativa per l'utente;
- minore rigidita` rispetto al modello Sanctum puro, perche' il token e` recuperabile lato server in forma cifrata.

La scelta e` accettabile se questa esigenza di usabilita` e` prioritaria e se `APP_KEY` viene trattata come materiale altamente sensibile.
