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:
2026-03-11 12:53:25 -07:00
parent 9ef913c59b
commit 14083b82b4
21 changed files with 760 additions and 130 deletions

View File

@@ -219,6 +219,92 @@ See ARCHITECTURE.md for design rationale.
---
## Phase 6 — mciasdb: Database Maintenance Tool
See ARCHITECTURE.md §16 for full design rationale, trust model, and command
surface.
### Step 6.1: `cmd/mciasdb` — binary skeleton and config loading
**Acceptance criteria:**
- Binary at `cmd/mciasdb/main.go` parses `--config` flag
- Loads `[database]` and `[master_key]` sections from mciassrv config format
- Derives master key (passphrase or keyfile, identical logic to mciassrv)
- Opens SQLite DB with WAL mode and FK enforcement (reuses `internal/db`)
- Exits with error if DB cannot be opened (e.g., busy-timeout exceeded)
- Help text lists all subcommands
### Step 6.2: Schema subcommands
**Acceptance criteria:**
- `mciasdb schema verify` — opens DB, reports current schema version, exits 0
if up-to-date, exits 1 if migrations pending
- `mciasdb schema migrate` — applies any pending migrations, reports each one
applied, exits 0
- Tests: verify on fresh DB reports version 0; migrate advances to current
version; verify after migrate exits 0
### Step 6.3: Account and role subcommands
**Acceptance criteria:**
- `mciasdb account list` — prints uuid, username, type, status for all accounts
- `mciasdb account get --id UUID` — prints single account record
- `mciasdb account create --username NAME --type human|system` — inserts row,
prints new UUID
- `mciasdb account set-password --id UUID` — prompts twice (confirm), re-hashes
with Argon2id, updates row; no `--password` flag permitted
- `mciasdb account set-status --id UUID --status STATUS` — updates status
- `mciasdb account reset-totp --id UUID` — clears totp_required and
totp_secret_enc
- `mciasdb role list --id UUID` — prints roles
- `mciasdb role grant --id UUID --role ROLE` — inserts role row
- `mciasdb role revoke --id UUID --role ROLE` — deletes role row
- All write operations append an audit log row with actor tagged `mciasdb`
- Tests: each subcommand happy path against in-memory SQLite; unknown UUID
returns error; set-password with mismatched confirmation returns error
### Step 6.4: Token subcommands
**Acceptance criteria:**
- `mciasdb token list --id UUID` — prints jti, issued_at, expires_at,
revoked_at for account
- `mciasdb token revoke --jti JTI` — sets revoked_at = now on the row
- `mciasdb token revoke-all --id UUID` — revokes all non-revoked tokens for
account
- `mciasdb prune tokens` — deletes rows from `token_revocation` where
expires_at < now; prints count removed
- All write operations append an audit log row
- Tests: revoke on unknown JTI returns error; revoke-all on account with no
active tokens is a no-op (exits 0); prune removes only expired rows
### Step 6.5: Audit log subcommands
**Acceptance criteria:**
- `mciasdb audit tail [--n N]` — prints last N events (default 50), newest last
- `mciasdb audit query --account UUID` — filters by actor_id or target_id
- `mciasdb audit query --type EVENT_TYPE` — filters by event_type
- `mciasdb audit query --since TIMESTAMP` — filters by event_time >= RFC-3339
timestamp
- Flags are combinable (AND semantics)
- `--json` flag on any audit subcommand emits newline-delimited JSON
- Tests: tail returns correct count; query filters correctly; --json output is
valid JSON
### Step 6.6: Postgres credentials subcommands
**Acceptance criteria:**
- `mciasdb pgcreds get --id UUID` — decrypts and prints host, port, db,
username, password with a warning header that output is sensitive
- `mciasdb pgcreds set --id UUID --host H --port P --db D --user U` — prompts
for password interactively (no `--password` flag), encrypts with AES-256-GCM,
stores row
- All write operations append an audit log row
- Tests: get on account with no pgcreds returns error; set then get round-trips
correctly (decrypted value matches original)
### Step 6.7: .gitignore and documentation
**Acceptance criteria:**
- `.gitignore` updated to exclude `mciasdb` binary
- README.md updated with mciasdb usage section (when to use vs mciasctl,
config requirements, example commands)
- `PROGRESS.md` updated to reflect Phase 6 complete
---
## Implementation Order
```
@@ -227,6 +313,7 @@ Phase 0 → Phase 1 (1.1, 1.2, 1.3, 1.4 in parallel or sequence)
→ Phase 3 (3.1, 3.2, 3.3 in sequence)
→ Phase 4
→ Phase 5
→ Phase 6 (6.1 → 6.2 → 6.3 → 6.4 → 6.5 → 6.6 → 6.7)
```
Each step must have passing tests before the next step begins.