Authentication¶
Authentication mechanisms¶
| Mechanism | Supported? | Notes |
|---|---|---|
Session cookie acugis_session |
Yes | Primary browser auth; also used by CLI password login |
| Bearer personal access token | Yes | Authorization: Bearer agp_... |
| JWT | No | TokenClaims type exists as a future placeholder only |
| OAuth / OIDC / SAML | No | Not implemented in Central |
| API keys (non-PAT) | No | PATs are the automation credential |
| Basic Auth | No |
Resolution order in shared/auth.Service.GetCurrentUser:
- Valid
acugis_sessioncookie - Else
Authorization: BearerPAT
Invalid/expired cookies fall through to bearer auth.
Session cookies¶
| Attribute | Value |
|---|---|
| Name | acugis_session |
| Path | / |
| Domain | host-only, or ACUGIS_SESSION_COOKIE_DOMAIN |
| HttpOnly | true |
| SameSite | Lax |
| Secure | true when TLS or X-Forwarded-Proto: https |
| Default TTL | 24h (CENTRAL_SESSION_TTL / AUTH_SESSION_TTL) |
Server storage stores only SHA-256(token) hex in dashboard_sessions. Login creates the cookie; logout deletes the session row and clears the cookie.
Login / logout endpoints¶
| Method | Path | Body | Result |
|---|---|---|---|
GET |
/login |
— | Login HTML, or 303 if already authenticated |
POST |
/login |
form username, password, optional next |
303 + cookie on success; 401 HTML on bad credentials |
GET/POST |
/logout |
— | Deletes session, expires cookie, 303 to /login |
Notes verified from source:
- Login looks up username only (UI may say “username or email”, but email login is not implemented).
nextmust be a same-host relative path; absolute/////loginvalues are discarded.- Without a configured auth database,
POST /loginreturns503.
Personal access tokens (API keys for automation)¶
| Item | Detail |
|---|---|
| Prefix | agp_ |
| Creation | POST /api/me/tokens (authenticated user) |
| Listing | GET /api/me/tokens (non-revoked; expired may appear with active=false) |
| Revocation | DELETE /api/me/tokens/{id} (owner only; soft revoke) |
| Header | Authorization: Bearer agp_<secret> |
| Persistence | hash + 12-character display prefix; plaintext returned once |
| Scopes | Column exists; create currently stores empty scopes |
UI for tokens lives under /account.
Authorization model¶
Roles / groups¶
Seeded groups:
| Group | Role |
|---|---|
Administrators |
Full admin; protected from rename/delete |
Editors |
Seeded named group |
Analysts |
Seeded named group |
Customers |
Seeded named group |
Public |
Public/anonymous grants; protected from rename/delete |
Admin status:
dashboard_users.is_adminand memberships in Administrators (plus legacy group-name heuristics inGroupsIncludeAdmin)- HTML/API admin gates use
user.IsAdmin
Permissions¶
Resource permission values:
| Permission | Meaning in checks |
|---|---|
view |
Read/discover |
edit |
Modify (also satisfies view) |
admin |
Administer (also satisfies view/edit) |
HasPermission always includes the Public group when evaluating grants.
Portal card visibility¶
| Card kind | Rule |
|---|---|
| Admin viewer | Sees all cards |
| Manual card | Requires is_public=true |
| Resource-backed card | Needs ACL grant on matching resources row for viewer groups including Public |
Admin API authorization¶
All /api/admin/* and /admin/api/* handlers require:
- Auth database configured
- Authenticated session or PAT
IsAdmin == true
Unauthenticated JSON → 401 {"error":"authentication required"}.
Authenticated non-admin JSON → 403 {"error":"admin access required"}.
Browser HTML requests may redirect to /login or receive HTML forbidden responses.
Headers and cookies clients should send¶
| Name | Used for |
|---|---|
Cookie: acugis_session=... |
Session auth |
Authorization: Bearer agp_... |
PAT auth |
Accept: text/html vs JSON |
Chooses redirect vs JSON errors for some auth failures |
X-Forwarded-Proto |
Secure cookie + origin scheme (proxy-controlled) |
X-Forwarded-Host |
Discovery origin host |
X-Forwarded-Prefix |
Generated base path in links |
Central does not validate which peers may set forwarded headers; the reverse proxy must overwrite them.
Identity APIs¶
| Endpoint | Purpose |
|---|---|
GET /api/me |
Current authentication state (never requires login; returns authenticated:false when anonymous) |
GET/POST/DELETE /api/me/tokens* |
Manage caller’s PATs |
/api/admin/users* |
Admin user CRUD/password reset |
/api/admin/groups* |
Group CRUD and membership |
/api/admin/resources* / permissions* |
Resource registry and ACL management |
Security best practices¶
- Terminate TLS at the reverse proxy; ensure
X-Forwarded-Proto: httpsso session cookies are Secure. - Set
CENTRAL_ADMIN_PASSWORDbefore first boot; rotate if a generated password was journaled. - Treat PATs like passwords; store only in a secret manager; revoke unused tokens.
- Prefer database
sslmode=require(or stricter) in production. - Keep
/etc/central.envroot-readable only. - Do not expose Central’s listen port beyond localhost when Apache fronts the service.
- Be aware discovery logs the outbound Cookie header and bootstrap may log generated admin passwords.
- Protect Admin UI routes; membership in Administrators is powerful across the platform.
- Use host-only cookies unless a deliberate multi-subdomain domain is required and consistently configured.
- CSRF protection is not implemented; rely on SameSite=Lax, careful cookie scoping, and same-site deployments.
Explicit non-features¶
- No JWT issuance or validation path for API clients
- No OAuth authorization server or client flows
- No CORS middleware
- No rate limiting / lockout on login
- No email-based login despite some UI wording