159 lines
7.3 KiB
Markdown
159 lines
7.3 KiB
Markdown
# Service accounts en automatisering
|
|
|
|
Deze gids beschrijft scoped service accounts en tokens voor geautomatiseerde toegang
|
|
tot de API. Beheerders kunnen een tijdelijk, minimaal gemachtigd importtoken via
|
|
**Beheer** in de webapplicatie aanmaken en intrekken. De volledige levenscyclus blijft
|
|
ook via de API beschikbaar voor gecontroleerde automatisering.
|
|
|
|
## Wat is een service account?
|
|
|
|
Een service account is een niet-persoonlijke identiteit voor een geautomatiseerd
|
|
systeem (bijvoorbeeld een CI/CD-pipeline of, in de toekomst, een MCP-server) dat via de
|
|
API met het platform moet praten zonder een gewone gebruikersaanmelding te gebruiken.
|
|
|
|
- Een service account heeft één of meer **tokens**. Elk token heeft zijn eigen
|
|
**scopes** (rechten), een optionele vervaldatum en kan onafhankelijk van andere
|
|
tokens worden ingetrokken.
|
|
- Een token bewijst zichzelf met een `Authorization: Bearer <token>`-header, in plaats
|
|
van een sessiecookie.
|
|
- Scopes verruimen nooit de gewone workspace-rechten — ze beperken alleen wat een reeds
|
|
geauthenticeerde aanroep mag proberen. Een token met alleen `knowledge:search` kan
|
|
nooit een pagina aanmaken, ongeacht welke rol de aanmakende beheerder zelf heeft.
|
|
|
|
Service accounts aanmaken, tonen, tokens uitgeven en intrekken kan **alleen** door een
|
|
ingelogde beheerder (rol Eigenaar/Beheerder), via een gewone, cookie-geauthenticeerde
|
|
aanroep met CSRF-bescherming — nooit door een service account zelf. Een service account
|
|
kan dus nooit zijn eigen rechten verruimen of een nieuw token voor zichzelf aanmaken.
|
|
|
|
## Beschikbare scopes
|
|
|
|
| Scope | Betekenis |
|
|
| --- | --- |
|
|
| `knowledge:read` | Pagina's lezen |
|
|
| `knowledge:search` | Zoeken in de kennisbank |
|
|
| `pages:read` | Individuele pagina's ophalen |
|
|
| `pages:write` | Pagina's aanmaken/bewerken |
|
|
| `projects:read` | Projectdossiers en projectcontext lezen |
|
|
| `projects:write` | Projecten bewerken |
|
|
| `project-updates:append` | Een update aan een project toevoegen |
|
|
| `decisions:read` | Architectuurbeslissingen lezen |
|
|
| `decisions:write` | Architectuurbeslissingen aanmaken |
|
|
| `runbooks:read` | Runbooks lezen |
|
|
| `runbooks:write` | Runbooks aanmaken |
|
|
| `attachments:read` / `attachments:write` | Bijlagen lezen / uploaden |
|
|
| `imports:read` / `imports:execute` | Importstatus lezen / een import uitvoeren |
|
|
| `audit:read` | Audittrail lezen |
|
|
| `system:read` | Systeeminformatie lezen |
|
|
|
|
Een aanvraag met een onbekende scope wordt geweigerd (HTTP 422) — er is geen manier om
|
|
per ongeluk een niet-bestaande of verkeerd gespelde scope aan een token te koppelen.
|
|
|
|
## Een service account aanmaken
|
|
|
|
### Via de webapplicatie
|
|
|
|
1. Meld aan als beheerder en open **Beheer**.
|
|
2. Kies onder **Serviceaccounts** een van de drie vaste profielen, afhankelijk van de
|
|
taak:
|
|
- **Importserviceaccount aanmaken (pagina's en bijlagen)** — uitsluitend
|
|
`pages:read`, `pages:write`, `attachments:read` en `attachments:write`. Voor het
|
|
generieke Markdown-/bijlage-publicatietraject (`tools/knowledge-ingestion/`).
|
|
- **Automatiseringsserviceaccount aanmaken (infrastructuur, projecten,
|
|
runbooks)** — uitsluitend `infrastructure:read`, `infrastructure:write`,
|
|
`projects:read`, `projects:write`, `project-updates:append`, `runbooks:read` en
|
|
`runbooks:write`. Voor het synchroniseren van gecureerde infrastructuurfeiten
|
|
(`POST /inventory/curated-package`), het beheren van redactionele
|
|
serviceprofielen, en het publiceren van projectdossiers en runbooks.
|
|
- **Migratieserviceaccount aanmaken (LeafWiki-import)** — uitsluitend
|
|
`imports:read` en `imports:execute`. Voor een eenmalige, gecontroleerde
|
|
LeafWiki-migratie (`POST /admin/imports/preflight`/`/execute`/`/rollback`).
|
|
Deliberately gescheiden van het automatiseringsprofiel: een token voor dagelijkse
|
|
infrastructuur-/projectpublicatie mag nooit ook een migratie kunnen starten.
|
|
3. Kopieer het eenmalig getoonde token onmiddellijk naar de automatisering of een
|
|
geheimenbeheerder.
|
|
4. Trek het token na gebruik in via dezelfde beheerpagina.
|
|
|
|
Geen van beide vaste profielen dekt elke mogelijke automatisering — voor een taak die
|
|
een andere scopecombinatie nodig heeft (bijvoorbeeld alleen zoeken, of alleen
|
|
architectuurbeslissingen), gebruikt een beheerder de API hieronder met exact de
|
|
benodigde scopes, nooit ruimer dan nodig.
|
|
|
|
### Via de API
|
|
|
|
```bash
|
|
curl -X POST https://hub.example/api/v1/service-accounts \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-CSRF-Token: <csrf-token-van-huidige-sessie>" \
|
|
-b cookies.txt \
|
|
-d '{"name":"CI-bot","description":"Leest en doorzoekt de kennisbank vanuit de CI-pipeline.","scopes":["knowledge:search","pages:read"]}'
|
|
```
|
|
|
|
Het antwoord bevat het **ruwe token exact één keer**:
|
|
|
|
```json
|
|
{
|
|
"serviceAccountId": "…",
|
|
"tokenId": "…",
|
|
"rawToken": "ikh_<publieke-id>_<geheim>"
|
|
}
|
|
```
|
|
|
|
Bewaar dit token onmiddellijk in een geheimenbeheerder. Het platform slaat nooit de
|
|
ruwe waarde op — alleen een cryptografische hash — en kan het dus nadien nooit meer
|
|
tonen. Is het token kwijt, dan moet een nieuw token worden uitgegeven en het oude
|
|
worden ingetrokken.
|
|
|
|
## Een service account gebruiken
|
|
|
|
```bash
|
|
curl https://hub.example/api/v1/search?q=backup \
|
|
-H "Authorization: Bearer ikh_<publieke-id>_<geheim>"
|
|
```
|
|
|
|
Een aanroep zonder de vereiste scope wordt geweigerd — de mutatie of leesactie vindt
|
|
nooit plaats, ook al is het token op zich geldig.
|
|
|
|
## Tokens roteren
|
|
|
|
Geef eerst een nieuw token uit, werk de client bij, en trek pas daarna het oude token
|
|
in. Een service account is op deze manier nooit tijdelijk onbruikbaar tijdens rotatie:
|
|
|
|
```bash
|
|
curl -X POST https://hub.example/api/v1/service-accounts/<serviceAccountId>/tokens \
|
|
-H "Content-Type: application/json" -H "X-CSRF-Token: …" -b cookies.txt \
|
|
-d '{"scopes":["knowledge:search","pages:read"]}'
|
|
```
|
|
|
|
## Een token intrekken
|
|
|
|
```bash
|
|
curl -X POST https://hub.example/api/v1/service-accounts/tokens/<tokenId>/revoke \
|
|
-H "X-CSRF-Token: …" -b cookies.txt
|
|
```
|
|
|
|
Intrekking is onmiddellijk van kracht: de eerstvolgende aanroep met dat token wordt
|
|
geweigerd, zonder wachttijd.
|
|
|
|
## Herhaalde aanroepen veilig maken (Idempotency-Key)
|
|
|
|
Een aanmaak- of toevoegaanroep (bijvoorbeeld een nieuwe pagina, beslissing, runbook of
|
|
projectupdate) accepteert een optionele `Idempotency-Key`-header. Een netwerkfout
|
|
tijdens een eerdere poging kan zo veilig opnieuw worden geprobeerd zonder het risico op
|
|
een dubbele pagina of dubbele update:
|
|
|
|
- Dezelfde sleutel met exact dezelfde aanvraaginhoud: het eerder gegeven antwoord wordt
|
|
gewoon opnieuw teruggegeven, zonder de actie nogmaals uit te voeren.
|
|
- Dezelfde sleutel met een andere aanvraaginhoud: dit wordt geweigerd (HTTP 409) — er
|
|
wordt nooit stilzwijgend iets anders uitgevoerd onder een hergebruikte sleutel.
|
|
|
|
## Projectcontext voor automatisering
|
|
|
|
`GET /api/v1/projects/{projectId}/context` geeft een compacte, begrensde momentopname
|
|
van een project (huidige stand, recente updates, actieve mijlpalen, beslissingen,
|
|
runbooks, documenten) met stabiele citaten (`kind`, `id`, `revisie`, `titel`, pad,
|
|
laatst bijgewerkt) in één aanroep — bedoeld voor een toekomstige MCP-server die snel
|
|
projectcontext nodig heeft zonder tientallen losse aanroepen. Wanneer er meer items zijn
|
|
dan het maximum, toont het antwoord expliciet `truncation.truncated: true` met per
|
|
onderdeel het weggelaten aantal — er wordt nooit stilzwijgend informatie weggelaten
|
|
zonder dat te melden.
|