Commit Graph

  • da4126c1a9 Implement Phase 9: client libraries (Go, Rust, Lisp, Python) - clients/README.md: canonical API surface and error type reference - clients/testdata/: shared JSON response fixtures - clients/go/: mciasgoclient package; net/http + TLS 1.2+; sync.RWMutex token state; DisallowUnknownFields on all decoders; 25 tests pass - clients/rust/: async mcias-client crate; reqwest+rustls (no OpenSSL); thiserror MciasError enum; Arc<RwLock> token state; 22+1 tests pass; cargo clippy -D warnings clean - clients/lisp/: ASDF mcias-client; dexador HTTP, yason JSON; mcias-error condition hierarchy; Hunchentoot mock-dispatcher; 37 fiveam checks pass on SBCL 2.6.1; yason boolean normalisation in validate-token - clients/python/: mcias_client package (Python 3.11+); httpx sync; py.typed; dataclasses; 32 pytest tests; mypy --strict + ruff clean - test/mock/mockserver.go: in-memory mock server for Go client tests - ARCHITECTURE.md §19: updated per-language notes to match implementation - PROGRESS.md: Phase 9 marked complete - .gitignore: exclude clients/rust/target/, python .venv, .pytest_cache, .fasl files Security: token never logged or exposed in error messages in any library; TLS enforced in all four languages; token stored under lock/mutex/RwLock Kyle Isom 2026-03-11 16:38:32 -07:00
  • f34e9a69a0 Fix all golangci-lint warnings - errorlint: use errors.Is for db.ErrNotFound comparisons in accountservice.go, credentialservice.go, tokenservice.go - gofmt/goimports: move mciasv1 alias into internal import group in auth.go, credentialservice.go, grpcserver.go, grpcserver_test.go - gosec G115: add nolint annotation on int32 port conversions in mciasgrpcctl/main.go and credentialservice.go (port validated as [1,65535] on input; overflow not reachable) - govet fieldalignment: reorder Server, grpcRateLimiter, grpcRateLimitEntry, testEnv structs to reduce GC bitmap size (96 -> 80 pointer bytes each) - ineffassign: remove intermediate grpcSrv = GRPCServer() call in cmd/mciassrv/main.go (immediately overwritten by TLS build) - staticcheck SA9003: replace empty if-body with _ = Serve(lis) in grpcserver_test.go 0 golangci-lint issues; 137 tests pass (go test -race ./...) Kyle Isom 2026-03-11 15:24:07 -07:00
  • 941c71f2d1 Implement Phase 8: operational artifacts - Makefile: build/test/lint/generate/man/install/clean/dist/docker; CGO_ENABLED=1 throughout; VERSION from git describe --tags --always - Dockerfile: multi-stage (golang:1.26-bookworm builder -> debian:bookworm-slim runtime); non-root uid 10001 (mcias), VOLUME /data, EXPOSE 8443/9443; no toolchain in final image - dist/mcias.service: hardened systemd unit (ProtectSystem=strict, ProtectHome, PrivateTmp, NoNewPrivileges, MemoryDenyWriteExecute, CapabilityBoundingSet= empty, EnvironmentFile, LimitNOFILE=65536) - dist/mcias.env.example: passphrase env file template - dist/mcias.conf.example: fully-commented production TOML config - dist/mcias-dev.conf.example: local dev config (/tmp, short expiry) - dist/mcias.conf.docker.example: container config template - dist/install.sh: POSIX sh idempotent installer; creates mcias user/group, installs binaries, /etc/mcias, /var/lib/mcias, systemd unit, man pages; prints post-install instructions - man/man1/mciassrv.1: mdoc synopsis/config/API/signals/files - man/man1/mciasctl.1: mdoc all subcommands/env/examples - man/man1/mciasdb.1: mdoc trust model/safety/all subcommands - man/man1/mciasgrpcctl.1: mdoc gRPC commands/grpcurl example - README.md: user-facing quick-start, first-run setup, build instructions, CLI references, Docker deployment, security notes - .gitignore: added /bin/, dist/mcias_*.tar.gz, man/man1/*.gz Kyle Isom 2026-03-11 15:11:36 -07:00
  • 8f706f10ec Phase 8 plan: add Dockerfile step (Step 8.6) - PROJECT_PLAN.md: insert Step 8.6 (Dockerfile) before the documentation step (renumbered to 8.7); acceptance criteria cover multi-stage build, non-root runtime user, EXPOSE ports, VOLUME /data, dist/mcias.conf.docker.example, Makefile docker target, and image size target (<50 MB) - ARCHITECTURE.md §18: add Dockerfile to artifact inventory table; add Dockerfile Design section covering build stages, security properties (no shell, non-root uid 10001, TLS inside container), operator workflow, and the new Makefile docker target Kyle Isom 2026-03-11 14:47:07 -07:00
  • 7c79d00514 Sync docs: ARCHITECTURE, PROJECT, PROJECT_PLAN - ARCHITECTURE.md §12: add mciasdb, mciasgrpcctl, internal/grpcserver, proto/, and gen/ to the directory structure diagram - ARCHITECTURE.md §17: replace buf generate references with protoc; the implementation uses protoc + protoc-gen-go + protoc-gen-go-grpc invoked via go generate ./... (proto/generate.go) - PROJECT_PLAN.md §7.1: replace buf.yaml/buf.gen.yaml acceptance criteria with the protoc-based go:generate approach actually used - PROJECT_PLAN.md §7.6: clarify that gen/ is committed to the repo (not gitignored); only the binary /mciasgrpcctl is excluded - PROJECT.md: replace scrypt with Argon2id (the actual algorithm); remove the redundant Argon2 suggestion line Kyle Isom 2026-03-11 14:44:08 -07:00
  • 59d51a1d38 Implement Phase 7: gRPC dual-stack interface - proto/mcias/v1/: AdminService, AuthService, TokenService, AccountService, CredentialService; generated Go stubs in gen/ - internal/grpcserver: full handler implementations sharing all business logic (auth, token, db, crypto) with REST server; interceptor chain: logging -> auth (JWT alg-first + revocation) -> rate-limit (token bucket, 10 req/s, burst 10, per-IP) - internal/config: optional grpc_addr field in [server] section - cmd/mciassrv: dual-stack startup; gRPC/TLS listener on grpc_addr when configured; graceful shutdown of both servers in 15s window - cmd/mciasgrpcctl: companion gRPC CLI mirroring mciasctl commands (health, pubkey, account, role, token, pgcreds) using TLS with optional custom CA cert - internal/grpcserver/grpcserver_test.go: 20 tests via bufconn covering public RPCs, auth interceptor (no token, invalid, revoked -> 401), non-admin -> 403, Login/Logout/RenewToken/ValidateToken flows, AccountService CRUD, SetPGCreds/GetPGCreds AES-GCM round-trip, credential fields absent from all responses Security: JWT validation path identical to REST: alg header checked before signature, alg:none rejected, revocation table checked after sig. Authorization metadata value never logged by any interceptor. Credential fields (PasswordHash, TOTPSecret*, PGPassword) absent from all proto response messages — enforced by proto design and confirmed by test TestCredentialFieldsAbsentFromAccountResponse. Login dummy-Argon2 timing guard preserves timing uniformity for unknown users (same as REST handleLogin). TLS required at listener level; cmd/mciassrv uses credentials.NewServerTLSFromFile; no h2c offered. 137 tests pass, zero race conditions (go test -race ./...) Kyle Isom 2026-03-11 14:38:47 -07:00
  • 094741b56d Planning updates. Kyle Isom 2026-03-11 14:15:27 -07:00
  • e63d9863b6 Implement dashboard and audit log templates, add paginated audit log support Kyle Isom 2026-03-11 14:05:08 -07:00
  • 14083b82b4 Fix linting: golangci-lint v2 config, nolint annotations Kyle Isom 2026-03-11 12:53:25 -07:00
  • 9ef913c59b Updating ARCHITECTURE.md. Kyle Isom 2026-03-11 12:19:17 -07:00
  • f02eff21b4 Complete implementation: e2e tests, gofmt, hardening - Add test/e2e: 11 end-to-end tests covering full login/logout, token renewal, admin account management, credential-never-in-response, unauthorised access, JWT alg confusion and alg:none attacks, revoked token rejection, system account token issuance, wrong-password vs unknown-user indistinguishability - Apply gofmt to all source files (formatting only, no logic changes) - Update .golangci.yaml for golangci-lint v2 (version field required, gosimple merged into staticcheck, formatters section separated) - Update PROGRESS.md to reflect Phase 5 completion Security: All 97 tests pass with go test -race ./... (zero race conditions). Adversarial JWT tests (alg confusion, alg:none) confirm the ValidateToken alg-first check is effective against both attack classes. Credential fields (PasswordHash, TOTPSecret*, PGPassword) confirmed absent from all API responses via both unit and e2e tests. go vet ./... clean. golangci-lint v2.6.2 incompatible with go1.26 runtime; go vet used as linter until toolchain is updated. Kyle Isom 2026-03-11 11:54:14 -07:00
  • d75a1d6fd3 checkpoint mciassrv Kyle Isom 2026-03-11 11:48:24 -07:00
  • 9e4e7aba7a Adding docs. Kyle Isom 2026-03-11 11:26:47 -07:00
  • de0551c627 Initial import. Kyle Isom 2026-03-11 11:14:19 -07:00