Stored credential secrets are encrypted with a key derived from
ORCHESTRAD_SECRET_KEY. When that value changes, the secrets are intact but
unreadable, and the only symptom was an opaque "decryption failed" surfacing
deep inside an unrelated operation:
"preview failed: building LDAP client: failed to decrypt credential:
decryption failed"
Nothing pointed at the real cause, so the error is now self-diagnosing:
- ErrDecryptionFailed states that the data was encrypted under a different
ORCHESTRAD_SECRET_KEY (or is corrupted). GCM auth failure on a well-formed
ciphertext is overwhelmingly a wrong-key case.
- The three credential decrypt sites name the credential, so the operator
knows which password to restore or re-enter.
- New services.CheckSecretKey verifies every stored secret against the
current key. It runs at startup (LogSecretKeyCheck) and in `doctor`, so a
mismatched key is reported once, loudly, at the moment it is first used
rather than during the next rule run. A correctly-sized but *different*
key passed doctor's existing length check and still broke every bind.
Not fatal: the server still starts, since an operator may be mid-migration
or may intend to re-enter the secrets.
Verified on the demo instance: starting with a wrong key logs
"1 of 1 stored credential secret(s) CANNOT be decrypted ... [OrchestrAD]",
and the rule preview error now names both the credential and the key.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The OpenAPI spec and Swagger UI were public. Put them behind the same
authentication as the rest of the API, and add a compact route list so a
client can ask "what can I call?" without opening dev tools.
Access:
- /api/openapi.json and /api/routes require a bearer token or API key.
- /api/docs additionally accepts a session cookie set at login, so a
signed-in operator can open the docs in a new tab; an anonymous browser
is redirected to /login?redirect=... and returned afterwards.
- The cookie is HttpOnly and path-scoped to /api/docs, so it is never sent
to /api/v1/* and cannot authenticate an API call (no CSRF surface).
Verified: cookie-only request to /api/v1/rules returns 401.
Discovery: both the spec and GET /api/routes accept ?method=get,post and
?path=<substring> (comma-separated, case-insensitive). The route list
returns method, path, summary, tag, public, and `allowed` — false when a
read-scoped API key cannot invoke that route. /api/docs passes the same
query through to the spec it loads.
UI: a </> icon in the header (both layouts) and an Administration → API
Docs menu entry, opened in a new tab via a new `external` nav-item flag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Lower ORCHESTRAD_LOG_MAX_SIZE_MB default from 100 to 5 so log files roll
sooner by default; README updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- GET /api/docs serves a Swagger UI and GET /api/openapi.json serves an
OpenAPI 3 spec built by walking the live chi router, so documented paths
always match what the build serves. A small registry adds rich detail
(request bodies, params, schemas) for the automation-critical operations
(auth login, rule create/update/preview, connection introspection);
RuleInput and friends are defined as reusable component schemas.
- Add docs/examples/Create-OrchestrADRule.ps1: a no-alias PowerShell sample
that builds headers/body as typed dictionaries, serializes with
ConvertTo-Json, logs in, creates a SyncGroupMembership rule, and runs it.
- README: new "API & Automation" section (Swagger + PowerShell), and a
"Logging & Retention" section documenting log rotation and the new
database maintenance/retention knobs.
Tests cover spec generation from a router and registry well-formedness.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Change the default HTTP port from 8080 to 18090 and propagate it through the
Dockerfile (EXPOSE + healthcheck), docker-compose, and the README. Host default
stays 0.0.0.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add Installation (MSI/binary/Docker), Running & Service Management (the CLI
commands incl. idempotent initialize/remove), and CI/CD (two-job release +
required REGISTRY_PASSWORD secret) sections; note the pure-Go build. Add
dashboard/rules/credentials/login/schedules screenshots and a Screenshots
section.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>