Initial import.
This commit is contained in:
124
.golangci.yaml
Normal file
124
.golangci.yaml
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
# golangci-lint configuration for a security-critical IAM system.
|
||||||
|
# Principle: fail loudly. Security and correctness issues are errors, not warnings.
|
||||||
|
|
||||||
|
run:
|
||||||
|
timeout: 5m
|
||||||
|
# Include test files so security rules apply to test helpers too.
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
# --- Correctness ---
|
||||||
|
# Unhandled errors are silent failures; in auth code they become vulnerabilities.
|
||||||
|
- errcheck
|
||||||
|
# go vet: catches printf-verb mismatches, unreachable code, suspicious constructs.
|
||||||
|
- govet
|
||||||
|
# Detects assignments whose result is never used; dead writes hide logic bugs.
|
||||||
|
- ineffassign
|
||||||
|
# Reports code that is never executed.
|
||||||
|
- deadcode
|
||||||
|
# Detects variables and functions that are never used.
|
||||||
|
- unused
|
||||||
|
|
||||||
|
# --- Error handling ---
|
||||||
|
# Enforces proper error wrapping (errors.Is/As instead of == comparisons) and
|
||||||
|
# prevents accidental discard of wrapped sentinel errors.
|
||||||
|
- errorlint
|
||||||
|
# Detects returning (nil, nil) from functions that return (value, error), which
|
||||||
|
# is almost always a logic error in auth flows.
|
||||||
|
- nilnil
|
||||||
|
|
||||||
|
# --- Security ---
|
||||||
|
# Primary security scanner: hardcoded secrets, weak RNG, insecure crypto
|
||||||
|
# (MD5/SHA1/DES/RC4), SQL injection, insecure TLS, file permission issues, etc.
|
||||||
|
- gosec
|
||||||
|
# Deep static analysis: deprecated APIs, incorrect mutex use, unreachable code,
|
||||||
|
# incorrect string conversions, and hundreds of other checks.
|
||||||
|
- staticcheck
|
||||||
|
# Detects integer overflow-prone conversions (e.g., int64 → int32) that can
|
||||||
|
# corrupt length or index calculations in crypto/auth code.
|
||||||
|
- gosimple
|
||||||
|
|
||||||
|
# --- Style / conventions (per CLAUDE.md) ---
|
||||||
|
# Enforces gofmt formatting. Non-formatted code is a CI failure.
|
||||||
|
- gofmt
|
||||||
|
# Manages import grouping and formatting; catches stray debug imports.
|
||||||
|
- goimports
|
||||||
|
# Enforces Go naming conventions and exported-symbol documentation.
|
||||||
|
- revive
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
errcheck:
|
||||||
|
# Treat blank-identifier assignment of errors as a failure: `_ = riskyCall()`
|
||||||
|
check-blank: true
|
||||||
|
# Also check error returns from type assertions.
|
||||||
|
check-type-assertions: true
|
||||||
|
|
||||||
|
govet:
|
||||||
|
# Enable all analyzers, including shadow (variable shadowing is dangerous in
|
||||||
|
# auth code where an outer `err` may be silently clobbered).
|
||||||
|
enable-all: true
|
||||||
|
|
||||||
|
gosec:
|
||||||
|
# Treat all gosec findings as errors, not warnings.
|
||||||
|
severity: medium
|
||||||
|
confidence: medium
|
||||||
|
excludes:
|
||||||
|
# G104 (errors unhandled) overlaps with errcheck; let errcheck own this.
|
||||||
|
- G104
|
||||||
|
|
||||||
|
errorlint:
|
||||||
|
errorf: true
|
||||||
|
asserts: true
|
||||||
|
comparison: true
|
||||||
|
|
||||||
|
gofmt:
|
||||||
|
simplify: true
|
||||||
|
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: exported
|
||||||
|
severity: warning
|
||||||
|
- name: error-return
|
||||||
|
severity: error
|
||||||
|
- name: error-strings
|
||||||
|
severity: warning
|
||||||
|
- name: if-return
|
||||||
|
severity: warning
|
||||||
|
- name: increment-decrement
|
||||||
|
severity: warning
|
||||||
|
- name: var-naming
|
||||||
|
severity: warning
|
||||||
|
- name: package-comments
|
||||||
|
severity: warning
|
||||||
|
- name: range
|
||||||
|
severity: warning
|
||||||
|
- name: time-naming
|
||||||
|
severity: warning
|
||||||
|
- name: unexported-return
|
||||||
|
severity: error
|
||||||
|
- name: indent-error-flow
|
||||||
|
severity: warning
|
||||||
|
- name: early-return
|
||||||
|
severity: warning
|
||||||
|
|
||||||
|
issues:
|
||||||
|
# Do not cap the number of reported issues; in security code every finding matters.
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
max-same-issues: 0
|
||||||
|
|
||||||
|
# Exclude vendor and generated code only.
|
||||||
|
exclude-dirs:
|
||||||
|
- vendor
|
||||||
|
exclude-files:
|
||||||
|
- ".*\\.pb\\.go$"
|
||||||
|
- ".*_gen\\.go$"
|
||||||
|
|
||||||
|
exclude-rules:
|
||||||
|
# In test files, allow hardcoded test credentials (gosec G101) since they are
|
||||||
|
# intentional fixtures, not production secrets.
|
||||||
|
- path: "_test\\.go"
|
||||||
|
linters:
|
||||||
|
- gosec
|
||||||
|
text: "G101"
|
||||||
74
CLAUDE.md
Normal file
74
CLAUDE.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
MCIAS (Metacircular Identity and Access System) is a single-sign-on (SSO) and Identity & Access Management (IAM) system for personal projects. The target audience is a single developer building personal apps, with support for onboarding friends onto those apps.
|
||||||
|
|
||||||
|
**Priorities (in order):** security, robustness, correctness. Performance is secondary.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **Language:** Go
|
||||||
|
- **Database:** SQLite
|
||||||
|
- **Logging/Utilities:** git.wntrmute.dev/kyle/goutils
|
||||||
|
- **Crypto:** Ed25519 (signatures), Argon2 (password hashing)
|
||||||
|
- **Tokens:** JWT signed with Ed25519 (algorithm: EdDSA); always validate the `alg` header on receipt — never accept `none` or symmetric algorithms
|
||||||
|
- **Auth:** Username/password + optional TOTP; future FIDO/Yubikey support
|
||||||
|
|
||||||
|
## Binaries
|
||||||
|
|
||||||
|
- `mciassrv` — authentication server (REST API over HTTPS/TLS)
|
||||||
|
- `mciasctl` — admin CLI for account/token/credential management
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
If PROGRESS.md does not yet exist, create it before proceeding. It is the source of truth for current state.
|
||||||
|
|
||||||
|
1. Check PROGRESS.md for current state and next steps
|
||||||
|
2. Define discrete next steps with actionable acceptance criteria
|
||||||
|
3. Implement, adversarially verify correctness, write tests
|
||||||
|
4. Commit to git, update PROGRESS.md
|
||||||
|
5. Repeat
|
||||||
|
|
||||||
|
## Security Constraints
|
||||||
|
|
||||||
|
This is a security-critical project. The following rules are non-negotiable:
|
||||||
|
|
||||||
|
- Never implement custom crypto. Use standard library (`crypto/...`) or well-audited packages only.
|
||||||
|
- Always validate the `alg` header in JWTs before processing; reject `none` and any non-EdDSA algorithm.
|
||||||
|
- Argon2id parameters must meet current OWASP recommendations; never reduce them for convenience.
|
||||||
|
- Credential storage (passwords, tokens, secrets) must never appear in logs, error messages, or API responses.
|
||||||
|
- Any code touching authentication flows, token issuance/validation, or credential storage must include a comment citing the rationale for each security decision.
|
||||||
|
- When in doubt about a crypto or auth decision, halt and ask rather than guess.
|
||||||
|
- Review all crypto primitives against current best practices before use; flag any deviation in the commit body.
|
||||||
|
|
||||||
|
## Testing Requirements
|
||||||
|
|
||||||
|
- Tests live alongside source in the same package, using the `_test.go` suffix
|
||||||
|
- Run with `go test ./...`; CI must pass with zero failures
|
||||||
|
- Unit tests for all exported functions and security-critical internal functions
|
||||||
|
- Integration tests for all subsystems (database layer, token issuance, auth flows)
|
||||||
|
- End-to-end tests for complete login, token renewal, and revocation flows
|
||||||
|
- Adversarially verify all outputs: test invalid inputs, boundary conditions, and known attack patterns (e.g., JWT `alg` confusion, timing attacks on credential comparison)
|
||||||
|
- Use `crypto/subtle.ConstantTimeCompare` wherever token or credential equality is checked
|
||||||
|
|
||||||
|
## Git Commit Style
|
||||||
|
|
||||||
|
- First line: single line, max 55 characters
|
||||||
|
- Body (optional): bullet points describing work done
|
||||||
|
- Security-sensitive changes (crypto primitives, auth flows, token handling, credential storage, session management) must be explicitly flagged in the commit body with a `Security:` line describing what changed and why it is safe
|
||||||
|
|
||||||
|
## Go Conventions
|
||||||
|
|
||||||
|
- Format all code with `gofmt` before committing
|
||||||
|
- Lint with `golangci-lint`; resolve all warnings unless explicitly justified
|
||||||
|
- Wrap errors with `fmt.Errorf("context: %w", err)` to preserve stack context
|
||||||
|
- Prefer explicit error handling over panics; never silently discard errors
|
||||||
|
- Use `log/slog` (or goutils equivalents) for structured logging; never `fmt.Println` in production paths
|
||||||
|
|
||||||
|
## Key Documents
|
||||||
|
|
||||||
|
- `PROJECT.md` — Project specifications and requirements
|
||||||
|
- `ARCHITECTURE.md` — **Required before any implementation.** Covers token lifecycle, session management, multi-app trust boundaries, and database schema. Do not generate code until this document exists.
|
||||||
|
- `PROJECT_PLAN.md` — Discrete implementation steps (to be written)
|
||||||
|
- `PROGRESS.md` — Development progress tracking (to be written)
|
||||||
69
PROJECT.md
Normal file
69
PROJECT.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# MCIAS
|
||||||
|
|
||||||
|
We are building a single-signon and IAM system for personal projects.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
The Metacircular Identity and Access System (MCIAS) provides standard
|
||||||
|
tools for user and access management among metacircular and wntrmute
|
||||||
|
systems.
|
||||||
|
|
||||||
|
In particular, the target audience is a single developer building
|
||||||
|
personal apps. It should be easy to use MCIAS to facilitate onboarding
|
||||||
|
friends onto these personal apps.
|
||||||
|
|
||||||
|
MCIAS is a foundational security and identity system. As such, the
|
||||||
|
highest priorities are for security, robustness, and correctness.
|
||||||
|
Performance is secondary, and can be tuned later.
|
||||||
|
|
||||||
|
## Specifications
|
||||||
|
|
||||||
|
+ Applications should be able to either do an interactive login, using a
|
||||||
|
username/password (and potentially a TOTP), or present a token.
|
||||||
|
+ Applications should be able to renew the token, which would nominally
|
||||||
|
expire after some period (defaulting to maybe 30 days).
|
||||||
|
+ There are two kinds of users: human and system accounts.
|
||||||
|
+ System accounts can only present a token; they have a single token
|
||||||
|
associated with that account at a time.
|
||||||
|
+ User accounts have roles associated with them.
|
||||||
|
+ Users with the admin role can issue tokens for any app, or users with
|
||||||
|
the role named the same as a service account can issue tokens for that
|
||||||
|
service account.
|
||||||
|
+ Admin users can also revoke tokens for a service account.
|
||||||
|
+ Service accounts (and users with the a role named the same as the
|
||||||
|
service account) can also retrieve Postgres database credentials for
|
||||||
|
the service account.
|
||||||
|
+ Human accounts should eventually support FIDO logins and Yubikey auth,
|
||||||
|
but the first pass only needs username, password, and optional TOTP.
|
||||||
|
|
||||||
|
## Technical details
|
||||||
|
|
||||||
|
+ User passwords will be stored using scrypt.
|
||||||
|
+ The service account tokens and user/password authentication can be
|
||||||
|
used to obtain a JWT, if that is appropriate.
|
||||||
|
+ All authentication events should be logged.
|
||||||
|
+ This service should use the packages contained in
|
||||||
|
git.wntrmute.dev/kyle/goutils for logging etc.
|
||||||
|
+ The database should be sqlite.
|
||||||
|
+ Modern cryptography should be used. Preference should be given to
|
||||||
|
Ed25519 as the public algorithm for signatures, for example. Consider
|
||||||
|
the use of Argon2 for password hashes.
|
||||||
|
|
||||||
|
## Interfaces
|
||||||
|
|
||||||
|
+ The primary interface will be an REST API over HTTPS. TLS security is
|
||||||
|
critical for this.
|
||||||
|
+ We will also need to build client libraries in several languages
|
||||||
|
later on.
|
||||||
|
+ There should be two command line tools associated with MCIAS:
|
||||||
|
+ mciassrv is the authentication server.
|
||||||
|
+ mciasctl is the tool for admins to create and manage accounts, issue
|
||||||
|
or revoke tokens, and manage postgres database credentials.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
+ We need an explicit security model.
|
||||||
|
+ This is a system for small, personal services. Manual user lifecycle
|
||||||
|
managment is acceptable and expected. Federation is an explicit
|
||||||
|
nongoal.
|
||||||
|
+ Strong testing is a requirement.
|
||||||
31
README.md
Normal file
31
README.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
The project notes are in PROJECT.md.
|
||||||
|
|
||||||
|
Before starting the project, read the project description and develop a
|
||||||
|
system architecture document (ARCHITECTURE.md). It should describe the
|
||||||
|
technical design of the system. Then, PROJECT_PLAN.md should be written
|
||||||
|
that describes how to build this system in discrete steps.
|
||||||
|
|
||||||
|
Commit these files to Git after human review. For this project, all git
|
||||||
|
commits should have a single first line, no more than 55 characters,
|
||||||
|
that succinctly describes an overview of the changes. As necessary, the
|
||||||
|
body of the commit message should contain bullets describing the work
|
||||||
|
that was done.
|
||||||
|
|
||||||
|
Then, create PROGRESS.md. This should be initialized with the first
|
||||||
|
steps for the project.
|
||||||
|
|
||||||
|
The development process for this should generally be:
|
||||||
|
|
||||||
|
1. Determine the current state of the project. Track the progress in
|
||||||
|
PROGRESS.md, explicitly stating what was done and next steps.
|
||||||
|
2. Develop reasonable, discrete next steps to move forward with
|
||||||
|
actionable acceptance criteria.
|
||||||
|
3. Complete the next steps.
|
||||||
|
+ You should adversarially check whether any outputs are correct.
|
||||||
|
+ All code units should be thoroughly unit tested.
|
||||||
|
+ All subsystems should be thoroughly integration tested.
|
||||||
|
+ Where appropriate, end-to-end tests to validate the system should
|
||||||
|
be developed.
|
||||||
|
4. Checkpoint your work, committing it to git.
|
||||||
|
|
||||||
|
Repeat this cycle until the system is in the desired end state.
|
||||||
Reference in New Issue
Block a user