Commit Graph

  • a1250d05ee Merge pull request 'Update CLAUDE.md: fix tech stack, add key features' (#1) from update-claude-md-features into master master kyle 2026-04-02 22:20:21 +00:00
  • daba5032f7 Update CLAUDE.md: fix tech stack, add key features Kyle Isom 2026-04-02 15:14:41 -07:00
  • 15e7eb5bd1 Remove all inline JS from admin templates v1.10.5 Kyle Isom 2026-04-01 08:26:29 -07:00
  • e082671f53 Fix CSP-blocked inline handlers on SSO clients page v1.10.4 Kyle Isom 2026-04-01 08:22:17 -07:00
  • ef28805042 Fix template type error on SSO clients page v1.10.3 Kyle Isom 2026-04-01 08:09:01 -07:00
  • 33e0f9b8bd Fix SSO clients page template wrapper v1.10.2 Kyle Isom 2026-04-01 07:59:06 -07:00
  • 44a1b9ad3a Register SSO client templates v1.10.1 v1.10.0 Kyle Isom 2026-04-01 07:49:45 -07:00
  • df7773229c Move SSO clients from config to database Kyle Isom 2026-03-31 23:47:53 -07:00
  • 4430ce38a4 Allow htmx swap styles in CSP v1.9.3 Kyle Isom 2026-03-30 17:43:53 -07:00
  • 4ed2cecec5 Fix SSO redirect failing with htmx login form v1.9.2 Kyle Isom 2026-03-30 17:32:44 -07:00
  • 9385c3846d Fix protobuf runtime panic on startup v1.9.1 Kyle Isom 2026-03-30 15:55:15 -07:00
  • e450ade988 Add SSO authorization code flow (Phase 1) Kyle Isom 2026-03-30 15:21:48 -07:00
  • 5b5e1a7ed6 Use mcdsl/terminal for all password prompts v1.9.0 Kyle Isom 2026-03-28 11:40:11 -07:00
  • e4220b840e flake: install shell completions for both mciasctl and mciasgrpcctl Kyle Isom 2026-03-27 21:49:10 -07:00
  • cff7276293 mciasctl: convert from flag to cobra Kyle Isom 2026-03-27 21:48:24 -07:00
  • be3bc807b7 mciasgrpcctl: convert from flag to cobra Kyle Isom 2026-03-27 21:48:02 -07:00
  • ead32f72f8 Add MCR registry tagging and push target to Makefile Kyle Isom 2026-03-27 14:32:21 -07:00
  • d7d80c0f25 Bump flake.nix version to match latest tag Kyle Isom 2026-03-27 02:16:34 -07:00
  • 41d01edfb4 Migrate module path from kyle/ to mc/ org v1.8.0 clients/go/v0.2.0 Kyle Isom 2026-03-27 02:03:46 -07:00
  • 9b521f3d99 Add MCP deployment note to runbook Kyle Isom 2026-03-26 22:09:23 -07:00
  • 115f23a3ea Add Nix flake for mciasctl and mciasgrpcctl Kyle Isom 2026-03-25 21:01:21 -07:00
  • 35e96444aa Include account_type in token validation response clients/go/v0.1.0 Kyle Isom 2026-03-25 17:45:04 -07:00
  • db7cd73a6e Fix WebAuthn login: username pre-fill and policy check Kyle Isom 2026-03-17 14:04:51 -07:00
  • 39d9ffb79a Add service-context login policy enforcement Kyle Isom 2026-03-16 21:09:38 -07:00
  • b0afe3b993 Align with engineering standards (steps 1-5) Kyle Isom 2026-03-16 20:26:43 -07:00
  • 446b3df52d Fix WebAuthn CSRF; clarify security key UI Kyle Isom 2026-03-16 19:27:44 -07:00
  • 0b37fde155 Add WebAuthn config; Docker single-mount Kyle Isom 2026-03-16 18:57:06 -07:00
  • 37afc68287 Add TOTP enrollment to web UI v1.7.0 Kyle Isom 2026-03-16 17:39:45 -07:00
  • 25417b24f4 Add FIDO2/WebAuthn passkey authentication Kyle Isom 2026-03-16 16:12:59 -07:00
  • 19fa0c9a8e Fix policy form roles; add JSON edit mode Claude Opus 4.6 2026-03-16 15:21:26 -07:00
  • 7db560dae4 Update PROGRESS.md for docker-clean target Kyle Isom 2026-03-15 20:38:58 -07:00
  • 124d0cdcd1 Add docker image cleanup to clean target Kyle Isom 2026-03-15 20:38:38 -07:00
  • cf1f4f94be Fix Swagger server URLs to use correct hosts Kyle Isom 2026-03-15 20:33:39 -07:00
  • 52cc979814 Update PROGRESS.md: /docs swagger fix Kyle Isom 2026-03-15 19:19:29 -07:00
  • 8bf5c9033f Bundle swagger-ui assets locally for /docs Kyle Isom 2026-03-15 19:19:12 -07:00
  • cb661bb8f5 Checkpoint: fix all lint warnings Kyle Isom 2026-03-15 16:40:11 -07:00
  • 9657f18784 Fix OpenAPI spec parsing errors in Swagger UI v1.6.0 Kyle Isom 2026-03-15 16:29:53 -07:00
  • d4e8ef90ee Add policy-based authz and token delegation Kyle Isom 2026-03-15 14:40:16 -07:00
  • d6cc82755d Add username to token validate response Kyle Isom 2026-03-15 14:06:11 -07:00
  • 0d38bbae00 Add mciasdb rekey command Kyle Isom 2026-03-15 13:27:29 -07:00
  • 23a27be57e Fix login card nesting on htmx failure Kyle Isom 2026-03-15 08:31:40 -07:00
  • b1b52000c4 Sync docs and fix flaky renewal e2e test v1.5.1 Kyle Isom 2026-03-15 00:39:41 -07:00
  • d87b4b4042 Add vault seal/unseal lifecycle Kyle Isom 2026-03-14 23:55:37 -07:00
  • 5c242f8abb Remediate PEN-01 through PEN-07 (pentest round 4) Kyle Isom 2026-03-14 23:14:47 -07:00
  • 1121b7d4fd Harden deployment and fix PEN-01 Kyle Isom 2026-03-14 22:33:24 -07:00
  • 2a85d4bf2b Update AUDIT.md: all SEC findings remediated v1.5.0 Kyle Isom 2026-03-14 21:31:30 -07:00
  • 8f09e0e81a Rename Go client package from mciasgoclient to mcias - Update package declaration in client.go - Update error message strings to reference new package name - Update test package and imports to use new name - Update README.md documentation and examples with new package name - All tests pass Kyle Isom 2026-03-14 19:01:07 -07:00
  • 7e5fc9f111 Fix flaky gRPC renewal test timing Kyle Isom 2026-03-13 01:08:44 -07:00
  • cf02b8e2d8 Merge SEC-01: require password for TOTP enrollment Kyle Isom 2026-03-13 01:07:39 -07:00
  • fe780bf873 Merge SEC-03: require token proximity for renewal Kyle Isom 2026-03-13 01:07:34 -07:00
  • cb96650e59 Merge SEC-11: use json.Marshal for audit details Kyle Isom 2026-03-13 01:06:55 -07:00
  • bef5a3269d Merge SEC-09: hide admin nav links from non-admin users Kyle Isom 2026-03-13 01:06:50 -07:00
  • 6191c5e00a Merge SEC-02: normalize lockout response Kyle Isom 2026-03-13 01:05:56 -07:00
  • fa45836612 Merge SEC-08: atomic system token issuance Kyle Isom 2026-03-13 00:50:39 -07:00
  • 0bc7943d8f Merge SEC-06: gRPC proxy-aware rate limiting Kyle Isom 2026-03-13 00:50:32 -07:00
  • 97ba7ab74c Merge SEC-04: API security headers Kyle Isom 2026-03-13 00:50:27 -07:00
  • 582645f9d6 Merge SEC-05: body size limit and max password length Kyle Isom 2026-03-13 00:49:39 -07:00
  • 8840317cce Merge SEC-10: add Permissions-Policy header Kyle Isom 2026-03-13 00:49:34 -07:00
  • 482300b8b1 Merge SEC-12: reduce default token expiry to 7 days Kyle Isom 2026-03-13 00:49:29 -07:00
  • 8545473703 Fix SEC-01: require password for TOTP enroll Kyle Isom 2026-03-13 00:48:31 -07:00
  • 3b17f7f70b Fix SEC-11: use json.Marshal for audit details Kyle Isom 2026-03-13 00:46:00 -07:00
  • eef7d1bc1a Fix SEC-03: require token proximity for renewal Kyle Isom 2026-03-13 00:45:35 -07:00
  • d7d7ba21d9 Fix SEC-09: hide admin nav links from non-admin users Kyle Isom 2026-03-13 00:44:30 -07:00
  • 4d3d438253 Fix SEC-02: normalize lockout response Kyle Isom 2026-03-13 00:43:57 -07:00
  • 7cc2c86300 Fix SEC-12: reduce default token expiry to 7 days Kyle Isom 2026-03-13 00:43:20 -07:00
  • 51a5277062 Fix SEC-08: make system token issuance atomic Kyle Isom 2026-03-13 00:43:13 -07:00
  • d3b63b1f87 Fix SEC-06: proxy-aware gRPC rate limiting Kyle Isom 2026-03-13 00:43:09 -07:00
  • 70e4f715f7 Fix SEC-05: add body size limit to REST API and max password length Kyle Isom 2026-03-13 00:42:11 -07:00
  • 3f09d5eb4f Fix SEC-04: add security headers to API Kyle Isom 2026-03-13 00:41:48 -07:00
  • 036a0b8be4 Fix SEC-07: disable static file directory listing Kyle Isom 2026-03-13 00:41:46 -07:00
  • 30fc3470fa Fix SEC-10: add Permissions-Policy header Kyle Isom 2026-03-13 00:41:20 -07:00
  • 586d4e3355 Allow non-admin users to access dashboard Kyle Isom 2026-03-12 23:40:21 -07:00
  • 394a9fb754 Update docs for recent changes Kyle Isom 2026-03-12 23:07:41 -07:00
  • 1c16354725 fix UI privilege escalation vulnerability v1.4.0 Kyle Isom 2026-03-12 21:59:02 -07:00
  • 89f78a38dd Update web UI to support all compile-time roles - Update knownRoles to include guest, viewer, editor, and commenter - Replace hardcoded role strings with model constants - Remove obsolete 'service' role from UI - All tests pass Kyle Isom 2026-03-12 21:14:22 -07:00
  • 4d6c5cb67c Add guest, viewer, editor, and commenter roles to compile-time allowlist - Add RoleGuest, RoleViewer, RoleEditor, and RoleCommenter constants - Update allowedRoles map to include new roles - Update ValidateRole error message with complete role list - All tests pass; build verified v1.3.0 Kyle Isom 2026-03-12 21:03:24 -07:00
  • f880bbb6de Add granular role grant/revoke endpoints to REST and gRPC APIs - Add POST /v1/accounts/{id}/roles and DELETE /v1/accounts/{id}/roles/{role} REST endpoints - Add GrantRole and RevokeRole RPCs to AccountService in gRPC API - Update OpenAPI specification with new endpoints - Add grant and revoke subcommands to mciasctl - Add grant and revoke subcommands to mciasgrpcctl - Regenerate proto files with new message types and RPCs - Implement gRPC server methods for granular role management - All existing tests pass; build verified with goimports Security: Role changes are audited via EventRoleGranted and EventRoleRevoked events, consistent with existing SetRoles implementation. Kyle Isom 2026-03-12 20:55:49 -07:00
  • d3d656a23f grpcctl: add auth login and policy commands Kyle Isom 2026-03-12 20:51:10 -07:00
  • 28bc33a96d clients: expand Go, Python, Rust client APIs v1.2.0 Kyle Isom 2026-03-12 20:29:11 -07:00
  • 98ed858c67 trusted proxy, TOTP replay protection, new tests Kyle Isom 2026-03-12 17:44:01 -07:00
  • 35f27b7c4f UI: password change enforcement + migration recovery Kyle Isom 2026-03-12 15:33:19 -07:00
  • 25d550a066 ignore env file v1.1.0 Kyle Isom 2026-03-12 14:39:14 -07:00
  • 5d7d2cfc08 Checkpoint: password reset, rule expiry, migrations Kyle Isom 2026-03-12 14:38:38 -07:00
  • 833775de83 db: integrate golang-migrate for schema migrations - internal/db/migrations/: five embedded SQL files containing the migration SQL previously held as Go string literals. Files follow the NNN_description.up.sql naming convention required by golang-migrate's iofs source. - internal/db/migrate.go: rewritten to use github.com/golang-migrate/migrate/v4 with the database/sqlite driver (modernc.org/sqlite, pure Go) and source/iofs for compile-time embedded SQL. - newMigrate() opens a dedicated *sql.DB so m.Close() does not affect the caller's shared connection. - Migrate() includes a compatibility shim: reads the legacy schema_version table and calls m.Force(v) before m.Up() so existing databases are not re-migrated. - LatestSchemaVersion promoted from var to const. - internal/db/db.go: added path field to DB struct; Open() translates ':memory:' to a named shared-cache URI (file:mcias_N?mode=memory&cache=shared) so the migration runner can open a second connection to the same in-memory database without sharing the handle that golang-migrate will close on teardown. - go.mod: added golang-migrate/migrate/v4 v4.19.1 (direct). All callers unchanged. All tests pass; golangci-lint clean. Kyle Isom 2026-03-12 11:52:39 -07:00
  • 562aad908e UI: pgcreds create button; show logged-in user Kyle Isom 2026-03-12 11:38:57 -07:00
  • 68df2eee23 Release v1.0.0 v1.0.0 Kyle Isom 2026-03-11 23:29:29 -07:00
  • 3d0eff9e0e docker: also tag image as mcias:latest Kyle Isom 2026-03-11 23:29:11 -07:00
  • 614c83c803 Add PG creds + policy/tags UI; fix lint and build Kyle Isom 2026-03-11 23:24:03 -07:00
  • fdcc117c89 Fix UI: install real HTMX, add PG creds and roles UI - web/static/htmx.min.js: replace placeholder stub with htmx 2.0.4 (downloaded from unpkg.com). The placeholder only logged a console warning; no HTMX features worked, so form submissions fell back to native POSTs and the account_row fragment was returned as a raw HTML body rather than spliced into the table. This was the root cause of account creation appearing to 'do nothing'. - internal/ui/ui.go: add pgcreds_form.html to shared template list; add PUT /accounts/{id}/pgcreds route; reorder AccountDetailData fields so embedded PageData does not shadow Account. - internal/ui/handlers_accounts.go: add handleSetPGCreds handler — encrypts the submitted password with AES-256-GCM using the server master key before storage, validates system-account-only constraint, re-reads and re-renders the fragment after save. Add PGCred field population to handleAccountDetail. - internal/ui/ui_test.go: add tests for account creation, role management, and PG credential handlers. - web/templates/account_detail.html: add Postgres Credentials card for system accounts. - web/templates/fragments/pgcreds_form.html: new fragment for the PG credentials form; CSRF token is supplied via the body-level hx-headers attribute in base.html. Security: PG password is encrypted with AES-256-GCM (crypto.SealAESGCM) before storage; a fresh nonce is generated per call; the plaintext is never logged or returned in responses. Kyle Isom 2026-03-11 22:30:13 -07:00
  • b495a90a9d Fix F-08, F-13: Adjust lockout expiration logic and enforce password length in tests Kyle Isom 2026-03-11 21:36:04 -07:00
  • 52f5d891eb Add checkpoint instructions. Kyle Isom 2026-03-11 21:31:45 -07:00
  • 3c94c948e2 Fix F-08, F-12, F-13: Implement account lockout, username validation, and password minimum length enforcement Kyle Isom 2026-03-11 20:59:26 -07:00
  • 2dbc553abe Fix F-07: pre-compute real Argon2 dummy hash via sync.Once - auth/auth.go: add DummyHash() which uses sync.Once to compute HashPassword("dummy-password-for-timing-only", DefaultArgonParams()) on first call; subsequent calls return the cached PHC string; add sync to imports - auth/auth_test.go: TestDummyHashIsValidPHC verifies the hash parses and verifies correctly; TestDummyHashIsCached verifies sync.Once behaviour; TestDummyHashMatchesDefaultParams verifies embedded m/t/p match DefaultArgonParams() - server/server.go, grpcserver/auth.go, ui/ui.go: replace five hardcoded PHC strings with auth.DummyHash() calls - AUDIT.md: mark F-07 as fixed Security: the previous hardcoded hash used a 6-byte salt and 6-byte output ("testsalt"/"testhash" in base64), which Argon2id verifies faster than a real 16-byte-salt / 32-byte-output hash. This timing gap was measurable and could aid user enumeration. auth.DummyHash() uses identical parameters and full-length salt and output, so dummy verification timing matches real timing exactly, regardless of future parameter changes. Kyle Isom 2026-03-11 20:37:27 -07:00
  • 06ec8be1c9 Fix F-16: revoke old system token before issuing new one - ui/handlers_accounts.go (handleIssueSystemToken): call GetSystemToken before issuing; if one exists, call RevokeToken(existing.JTI, "rotated") before TrackToken and SetSystemToken for the new token; mirrors the pattern in REST handleTokenIssue and gRPC IssueServiceToken - db/db_test.go: TestSystemTokenRotationRevokesOld verifies the full rotation flow: old JTI revoked with reason "rotated", new JTI tracked and active, GetSystemToken returns the new JTI - AUDIT.md: mark F-16 as fixed Security: without this fix an old system token remained valid after rotation until its natural expiry, giving a leaked or stolen old token extra lifetime. With the revocation the old JTI is immediately marked in token_revocation so any validator checking revocation status rejects it. Kyle Isom 2026-03-11 20:34:57 -07:00
  • e20b66d6f6 Fix F-02: replace password-in-hidden-field with nonce - ui/ui.go: add pendingLogin struct and pendingLogins sync.Map to UIServer; add issueTOTPNonce (generates 128-bit random nonce, stores accountID with 90s TTL) and consumeTOTPNonce (single-use, expiry-checked LoadAndDelete); add dummyHash() method - ui/handlers_auth.go: split handleLoginPost into step 1 (password verify → issue nonce) and step 2 (handleTOTPStep, consume nonce → validate TOTP) via a new finishLogin helper; password never transmitted or stored after step 1 - ui/ui_test.go: refactor newTestMux to reuse new newTestUIServer; add TestTOTPNonceIssuedAndConsumed, TestTOTPNonceUnknownRejected, TestTOTPNonceExpired, and TestLoginPostPasswordNotInTOTPForm; 11/11 tests pass - web/templates/fragments/totp_step.html: replace 'name=password' hidden field with 'name=totp_nonce' - db/accounts.go: add GetAccountByID for TOTP step lookup - AUDIT.md: mark F-02 as fixed Security: the plaintext password previously survived two HTTP round-trips and lived in the browser DOM during the TOTP step. The nonce approach means the password is verified once and immediately discarded; only an opaque random token tied to an account ID (never a credential) crosses the wire on step 2. Nonces are single-use and expire after 90 seconds to limit the window if one is captured. Kyle Isom 2026-03-11 20:33:04 -07:00
  • 0e201ae05b Fix F-03: make token renewal atomic - db/accounts.go: add RenewToken(oldJTI, reason, newJTI, accountID, issuedAt, expiresAt) which wraps RevokeToken + TrackToken in a single BEGIN/COMMIT transaction; if either step fails the whole tx rolls back, so the user is never left with neither old nor new token valid - server.go (handleRenewToken): replace separate RevokeToken + TrackToken calls with single RenewToken call; failure now returns 500 instead of silently losing revocation - grpcserver/auth.go (RenewToken): same replacement - db/db_test.go: TestRenewTokenAtomic verifies old token is revoked with correct reason, new token is tracked and not revoked, and a second renewal on the already-revoked old token returns an error - AUDIT.md: mark F-03 as fixed Security: without atomicity a crash/error between revoke and track could leave the old token active alongside the new one (two live tokens) or revoke the old token without tracking the new one (user locked out). The transaction ensures exactly one of the two tokens is valid at all times. Kyle Isom 2026-03-11 20:24:32 -07:00
  • c8f1ac6dac Fix F-01: TOTP enroll must not set required=1 early - db/accounts.go: add StorePendingTOTP() which writes totp_secret_enc and totp_secret_nonce but leaves totp_required=0; add comment explaining two-phase flow - server.go (handleTOTPEnroll): switch from SetTOTP() to StorePendingTOTP() so the required flag is only set after the user confirms a valid TOTP code via handleTOTPConfirm, which still calls SetTOTP() - server_test.go: TestTOTPEnrollDoesNotRequireTOTP verifies that after POST /v1/auth/totp/enroll, TOTPRequired is false and the encrypted secret is present; confirms that a subsequent login without a TOTP code still succeeds (no lockout) - AUDIT.md: mark F-01 and F-11 as fixed Security: without this fix an admin who enrolls TOTP but abandons before confirmation is permanently locked out because totp_required=1 but no confirmed secret exists. StorePendingTOTP() keeps the secret pending until the user proves possession by confirming a valid code. Kyle Isom 2026-03-11 20:18:57 -07:00
  • 47847a4312 Fix F-04 + F-11; add AUDIT.md - AUDIT.md: security audit report with 16 findings (F-01..F-16) - F-04 (server.go): wire loginRateLimit (10 req/s, burst 10) to POST /v1/auth/login and POST /v1/token/validate; no limit on /v1/health or public-key endpoints - F-04 (server_test.go): TestLoginRateLimited uses concurrent goroutines (sync.WaitGroup) to fire burst+1 requests before Argon2id completes, sidestepping token-bucket refill timing; TestTokenValidateRateLimited; TestHealthNotRateLimited - F-11 (ui.go): refactor Register() so all UI routes are mounted on a child mux wrapped with securityHeaders middleware; five headers set on every response: Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, HSTS, Referrer-Policy - F-11 (ui_test.go): 7 new tests covering login page, dashboard redirect, root redirect, static assets, CSP directives, HSTS min-age, and middleware unit behaviour Security: rate limiter on login prevents brute-force credential stuffing; security headers mitigate clickjacking (X-Frame-Options DENY), MIME sniffing (nosniff), and protocol downgrade (HSTS) Kyle Isom 2026-03-11 20:18:09 -07:00
  • f2903ca103 Fix grpcserver rate limiter: move to Server field Kyle Isom 2026-03-11 19:20:32 -07:00
  • 4d140886ca Add HTMX-based UI templates and handlers for account and audit management Kyle Isom 2026-03-11 18:02:53 -07:00