Document every exported symbol and how callers use the library.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-29 19:25:45 +02:00
co-authored by Cursor
parent bffc0c1a4d
commit b4281445cc
6 changed files with 630 additions and 53 deletions
+21 -49
View File
@@ -4,66 +4,38 @@ Short-lived RS256 user tokens from a Nextcloud ExApp to Go Microservices.
Import: `gitea.neitzel.de/konrad/go-usertoken` (package `usertoken`).
```bash
go get gitea.neitzel.de/konrad/go-usertoken
```
The ExApp mints a token after AppAPI has named the user. Each Microservice checks that token. One process trusts either a static public key or an OIDC issuer. The same bearer is forwarded when a Microservice calls another.
Procedure and claim rules: Knowledge `platforms/nextcloud/exapps/authentication.md`. Domain words: [CONTEXT.md](./CONTEXT.md).
- [Guide](docs/guide.md) — how to mint and how to verify
- [API](docs/api.md) — every exported symbol
- [Domain language](CONTEXT.md)
This module does not speak AppAPI and does not see `APP_SECRET`.
Procedure and claim rules: Knowledge `platforms/nextcloud/exapps/authentication.md`.
## ExApp
## Included
```go
signer, err := usertoken.NewSignerFromEnv()
raw, err := signer.Mint(time.Now(), usertoken.MintInput{
Subject: userID,
Groups: &groupIDs, // nil omits groups
})
req.Header.Set("Authorization", "Bearer "+raw)
```
- [ExApp](docs/guide.md#exapp) — mint a token, including key generation
- [Microservice](docs/guide.md#microservice) — verify a bearer and forward it
| Variable | Role |
| --- | --- |
| `USER_TOKEN_PRIVATE_KEY_FILE` | RSA private key PEM |
| `USER_TOKEN_ISSUER` | `iss` string |
| `USER_TOKEN_AUDIENCE` | `aud` string |
| `USER_TOKEN_TTL` | optional, default `5m` |
## Excluded
## Microservice
- AppAPI and `APP_SECRET`
- Choosing the Nextcloud user (the ExApp already has that id)
```go
auth, err := usertoken.FromEnv(ctx)
handler = auth.Middleware()(handler)
## Testing
caller, _ := usertoken.CallerFromContext(r.Context())
raw, _ := usertoken.BearerFromContext(r.Context())
out.Header.Set("Authorization", "Bearer "+raw)
```
Unit tests cover minting, static verification, and the HTTP and gRPC interceptors. OIDC tests do not need a live issuer unless a test starts one.
`/health` is not authenticated. Any other path without a valid bearer is 401.
Set one of these. Setting both, or neither, makes `FromEnv` fail.
Static public key (ExApp-minted tokens):
| Variable | Role |
| --- | --- |
| `USER_TOKEN_PUBLIC_KEY_FILE` | RSA public key PEM |
| `USER_TOKEN_ISSUER` | expected `iss` |
| `USER_TOKEN_AUDIENCE` | expected `aud` |
| `USER_TOKEN_SKEW` | optional, default `1m` |
OIDC issuer (Keycloak or another identity server):
| Variable | Role |
| --- | --- |
| `OIDC_ISSUER` | issuer URL that serves discovery |
| `OIDC_AUDIENCE` | expected `aud`; empty skips the check |
| `OIDC_GROUPS_CLAIM` | group array claim, default `groups` (`identity_groups` for current Keycloak tokens) |
| `USER_TOKEN_SKEW` | optional, default `1m` |
`go test ./...` fails when [`docs/api.md`](docs/api.md) does not match the exported API. Regenerate it with:
```bash
openssl genrsa -out user-token.key 2048
openssl rsa -in user-token.key -pubout -out user-token.pub
UPDATE_API_DOCS=1 go test -run TestAPIDoc -count=1
```
The private key stays on the ExApp. Static mode copies `user-token.pub` to each Microservice.
## Related
- Knowledge `platforms/nextcloud/exapps/authentication.md` — procedure and claims