Fix linting: golangci-lint v2 config, nolint annotations
* Rewrite .golangci.yaml to v2 schema: linters-settings -> linters.settings, issues.exclude-rules -> issues.exclusions.rules, issues.exclude-dirs -> issues.exclusions.paths * Drop deprecated revive exported/package-comments rules: personal project, not a public library; godoc completeness is not a CI req * Add //nolint:gosec G101 on PassphraseEnv default in config.go: environment variable name is not a credential value * Add //nolint:gosec G101 on EventPGCredUpdated in model.go: audit event type string, not a credential Security: no logic changes. gosec G101 suppressions are false positives confirmed by code inspection: neither constant holds a credential value.
This commit is contained in:
116
ARCHITECTURE.md
116
ARCHITECTURE.md
@@ -573,3 +573,119 @@ The `cmd/` packages are thin wrappers that wire dependencies and call into
|
||||
- **Master key loss:** Loss of the master key means all encrypted secrets
|
||||
(TOTP, Postgres passwords, signing key) are unrecoverable. Operators must
|
||||
back up the passphrase/keyfile securely.
|
||||
|
||||
---
|
||||
|
||||
## 16. mciasdb — Database Maintenance Tool
|
||||
|
||||
### Rationale
|
||||
|
||||
`mciasctl` is an API client: it requires a running mciassrv, a valid admin
|
||||
JWT, and network access. This is appropriate for normal administration but
|
||||
rules it out for several important scenarios:
|
||||
|
||||
- The server is down and accounts need to be inspected or repaired.
|
||||
- Bootstrap: creating the first admin account before any JWT can exist.
|
||||
- Offline forensics: reading the audit log without starting the server.
|
||||
- Maintenance: pruning expired token rows, verifying schema integrity.
|
||||
- Recovery: resetting a locked-out admin password when no other admin exists.
|
||||
|
||||
Adding direct DB access to `mciasctl` would blur the API-client / DB-operator
|
||||
trust boundary and create pressure to use the bypass path for routine tasks.
|
||||
A separate binary (`mciasdb`) makes the distinction explicit: it is a
|
||||
break-glass tool that requires local filesystem access to the SQLite file and
|
||||
the master key, and should only be used when the API is unavailable or
|
||||
insufficient.
|
||||
|
||||
### Trust Model
|
||||
|
||||
`mciasdb` is a privileged, local-only tool. It assumes:
|
||||
|
||||
- The operator has filesystem access to the SQLite database file.
|
||||
- The operator has the master key (passphrase env var or keyfile), same as
|
||||
mciassrv.
|
||||
- No network connection is required or used.
|
||||
- Audit events written by mciasdb are tagged with actor `mciasdb` (no UUID)
|
||||
so they are distinguishable from API-driven events in the audit log.
|
||||
|
||||
### Configuration
|
||||
|
||||
`mciasdb` accepts a subset of the mciassrv config file (the `[database]` and
|
||||
`[master_key]` sections) via `--config` flag, identical in format to
|
||||
mciassrv's config. This avoids a separate config format and ensures key
|
||||
derivation is identical.
|
||||
|
||||
### Command Surface
|
||||
|
||||
```
|
||||
mciasdb --config PATH <subcommand> [flags]
|
||||
```
|
||||
|
||||
**Schema / maintenance:**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb schema verify` | Open DB, run migrations in dry-run mode, report version |
|
||||
| `mciasdb schema migrate` | Apply any pending migrations and exit |
|
||||
| `mciasdb prune tokens` | Delete expired rows from `token_revocation` and `system_tokens` |
|
||||
|
||||
**Account management (offline):**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb account list` | Print all accounts (uuid, username, type, status) |
|
||||
| `mciasdb account get --id UUID` | Print single account record |
|
||||
| `mciasdb account create --username NAME --type human\|system` | Insert account row directly |
|
||||
| `mciasdb account set-password --id UUID` | Prompt for new password, re-hash with Argon2id, update row |
|
||||
| `mciasdb account set-status --id UUID --status active\|inactive\|deleted` | Update account status |
|
||||
| `mciasdb account reset-totp --id UUID` | Clear TOTP fields (totp_required=0, totp_secret_enc=NULL) |
|
||||
|
||||
**Role management (offline):**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb role list --id UUID` | List roles for account |
|
||||
| `mciasdb role grant --id UUID --role ROLE` | Insert role row |
|
||||
| `mciasdb role revoke --id UUID --role ROLE` | Delete role row |
|
||||
|
||||
**Token management (offline):**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb token list --id UUID` | List token_revocation rows for account |
|
||||
| `mciasdb token revoke --jti JTI` | Mark JTI as revoked in token_revocation |
|
||||
| `mciasdb token revoke-all --id UUID` | Revoke all active tokens for account |
|
||||
|
||||
**Audit log:**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb audit tail [--n N]` | Print last N audit events (default 50) |
|
||||
| `mciasdb audit query --account UUID` | Print audit events for account |
|
||||
| `mciasdb audit query --type EVENT_TYPE` | Print audit events of given type |
|
||||
| `mciasdb audit query --since TIMESTAMP` | Print audit events since RFC-3339 time |
|
||||
|
||||
**Postgres credentials (offline):**
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `mciasdb pgcreds get --id UUID` | Decrypt and print Postgres credentials |
|
||||
| `mciasdb pgcreds set --id UUID ...` | Encrypt and store Postgres credentials |
|
||||
|
||||
### Security Constraints
|
||||
|
||||
- `mciasdb account set-password` must prompt interactively (no `--password`
|
||||
flag) so the password is never present in shell history or process listings.
|
||||
- Decrypted secrets (TOTP secrets, Postgres passwords) are printed only when
|
||||
explicitly requested and include a warning that output should not be logged.
|
||||
- All writes produce an audit log entry tagged with actor `mciasdb`.
|
||||
- `mciasdb` must not start mciassrv or bind any network port.
|
||||
- mciasdb must refuse to open the DB if mciassrv holds an exclusive WAL lock;
|
||||
SQLite busy-timeout handles this gracefully (5s then error).
|
||||
|
||||
### Output Format
|
||||
|
||||
By default all output is human-readable text. `--json` flag switches to
|
||||
newline-delimited JSON for scripting. Credential fields follow the same
|
||||
`json:"-"` exclusion rules as the API — they are only printed when the
|
||||
specific `get` or `pgcreds get` command is invoked, never in list output.
|
||||
|
||||
Reference in New Issue
Block a user