Fix OpenAPI spec parsing errors in Swagger UI

- Replace type: [string, "null"] array syntax with
  type: string + nullable: true on AuditEvent.actor_id,
  AuditEvent.target_id, PolicyRule.not_before, and
  PolicyRule.expires_at; Swagger UI 5 cannot parse the
  JSON Schema array form
- Add missing username field to /v1/token/validate response
  schema (added to handler in d6cc827 but never synced)
- Add missing GET /v1/pgcreds endpoint to spec
- Sync web/static/openapi.yaml (served file) with root;
  the static copy was many commits out of date, missing
  all policy/tags schemas and endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-15 16:29:53 -07:00
parent d4e8ef90ee
commit 9657f18784
2 changed files with 838 additions and 89 deletions

View File

@@ -100,13 +100,15 @@ components:
format: date-time
example: "2026-03-11T09:01:23Z"
actor_id:
type: [string, "null"]
type: string
format: uuid
nullable: true
description: UUID of the account that performed the action. Null for bootstrap events.
example: 550e8400-e29b-41d4-a716-446655440000
target_id:
type: [string, "null"]
type: string
format: uuid
nullable: true
description: UUID of the affected account, if applicable.
ip_address:
type: string
@@ -205,16 +207,18 @@ components:
type: boolean
example: true
not_before:
type: [string, "null"]
type: string
format: date-time
nullable: true
description: |
Earliest time the rule becomes active. NULL means no constraint
(always active). Rules where `not_before > now()` are skipped
during evaluation.
example: "2026-04-01T00:00:00Z"
expires_at:
type: [string, "null"]
type: string
format: date-time
nullable: true
description: |
Time after which the rule is no longer active. NULL means no
constraint (never expires). Rules where expires_at is in the past
@@ -602,6 +606,10 @@ paths:
format: uuid
description: Subject (account UUID). Present when valid=true.
example: 550e8400-e29b-41d4-a716-446655440000
username:
type: string
description: Account username. Present when valid=true and the account exists.
example: alice
roles:
type: array
items:
@@ -615,7 +623,7 @@ paths:
example: "2026-04-10T12:34:56Z"
examples:
valid:
value: {valid: true, sub: "550e8400-...", roles: [editor], expires_at: "2026-04-10T12:34:56Z"}
value: {valid: true, sub: "550e8400-...", username: alice, roles: [editor], expires_at: "2026-04-10T12:34:56Z"}
invalid:
value: {valid: false}
"429":
@@ -1263,6 +1271,70 @@ paths:
"404":
$ref: "#/components/responses/NotFound"
/v1/pgcreds:
get:
summary: List accessible Postgres credentials
description: |
Return all Postgres credentials accessible to the authenticated account:
credentials owned by the account plus any explicitly granted by an admin.
The `id` field is the credential record ID; use it together with the
`service_account_id` to fetch full details via
`GET /v1/accounts/{id}/pgcreds`. Passwords are **not** returned by this
endpoint.
operationId: listAccessiblePGCreds
tags: [Admin — Credentials]
security:
- bearerAuth: []
responses:
"200":
description: Array of accessible Postgres credential summaries.
content:
application/json:
schema:
type: array
items:
type: object
required: [id, service_account_id, host, port, database, username, created_at, updated_at]
properties:
id:
type: integer
description: Credential record ID.
example: 7
service_account_id:
type: string
format: uuid
description: UUID of the system account that owns these credentials.
example: 550e8400-e29b-41d4-a716-446655440000
service_account_name:
type: string
description: Username of the owning system account (omitted if unavailable).
example: payments-api
host:
type: string
example: db.example.com
port:
type: integer
example: 5432
database:
type: string
example: mydb
username:
type: string
example: myuser
created_at:
type: string
format: date-time
example: "2026-03-11T09:00:00Z"
updated_at:
type: string
format: date-time
example: "2026-03-11T09:00:00Z"
"401":
$ref: "#/components/responses/Unauthorized"
"503":
$ref: "#/components/responses/VaultSealed"
/v1/audit:
get:
summary: Query audit log (admin)