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
This commit is contained in:
2026-03-11 15:11:36 -07:00
parent 8f706f10ec
commit 941c71f2d1
15 changed files with 1715 additions and 54 deletions

277
README.md
View File

@@ -1,32 +1,257 @@
The project notes are in PROJECT.md.
# MCIAS — Metacircular Identity and Access System
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.
MCIAS is a self-hosted SSO and IAM service for personal projects.
It provides authentication (JWT/Ed25519), account management, TOTP, and
Postgres credential storage over a REST API (HTTPS) and a gRPC API (TLS).
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.
See [ARCHITECTURE.md](ARCHITECTURE.md) for the technical design and
[PROJECT_PLAN.md](PROJECT_PLAN.md) for the implementation roadmap.
Then, create PROGRESS.md. This should be initialized with the first
steps for the project.
---
The development process for this should generally be:
## Quick Start
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.
+ All code changes must pass golangci-lint checks.
4. After each phase, checkpoint your work, committing it to git.
### Option A: Install from source
Repeat this cycle until the system is in the desired end state.
**Prerequisites:** Go 1.26+, a C compiler (required by modernc.org/sqlite).
```sh
git clone https://git.wntrmute.dev/kyle/mcias
cd mcias
make build # produces bin/mciassrv, other binaries
sudo make install
```
### Option B: Docker
```sh
docker build -t mcias:latest .
# or
make docker # tags mcias:<git-describe>
```
See [Deploying with Docker](#deploying-with-docker) below.
---
## First-Run Setup
### 1. Generate a TLS certificate
```sh
openssl req -x509 -newkey ed25519 -days 3650 \
-keyout /etc/mcias/server.key \
-out /etc/mcias/server.crt \
-subj "/CN=auth.example.com" \
-nodes
chmod 0640 /etc/mcias/server.key
chown root:mcias /etc/mcias/server.key
```
### 2. Configure the server
```sh
cp dist/mcias.conf.example /etc/mcias/mcias.conf
$EDITOR /etc/mcias/mcias.conf
chmod 0640 /etc/mcias/mcias.conf
chown root:mcias /etc/mcias/mcias.conf
```
Minimum required fields:
```toml
[server]
listen_addr = "0.0.0.0:8443"
tls_cert = "/etc/mcias/server.crt"
tls_key = "/etc/mcias/server.key"
[database]
path = "/var/lib/mcias/mcias.db"
[tokens]
issuer = "https://auth.example.com"
[master_key]
passphrase_env = "MCIAS_MASTER_PASSPHRASE"
```
See `dist/mcias.conf.example` for the fully-commented reference configuration.
For local development, use `dist/mcias-dev.conf.example`.
### 3. Set the master key passphrase
```sh
cp dist/mcias.env.example /etc/mcias/env
$EDITOR /etc/mcias/env # replace the placeholder passphrase
chmod 0640 /etc/mcias/env
chown root:mcias /etc/mcias/env
```
> **Important:** Back up the passphrase to a secure offline location.
> Losing it means losing access to all encrypted data in the database.
### 4. Create the first admin account
```sh
export MCIAS_MASTER_PASSPHRASE=your-passphrase
mciasdb --config /etc/mcias/mcias.conf account create \
--username admin --type human
mciasdb --config /etc/mcias/mcias.conf account set-password --id <UUID>
mciasdb --config /etc/mcias/mcias.conf role grant --id <UUID> --role admin
```
### 5. Start the server
```sh
# systemd
systemctl enable --now mcias
# manual
MCIAS_MASTER_PASSPHRASE=your-passphrase mciassrv -config /etc/mcias/mcias.conf
```
### 6. Verify
```sh
curl -k https://localhost:8443/v1/health
# {"status":"ok"}
```
---
## Building
```sh
make build # compile all binaries to bin/
make test # go test -race ./...
make lint # golangci-lint run ./...
make generate # regenerate protobuf stubs (requires protoc)
make man # build compressed man pages
make clean # remove bin/ and generated artifacts
make dist # cross-compiled tarballs for linux/amd64 and linux/arm64
make docker # build Docker image mcias:<version>
```
---
## Admin CLI (mciasctl)
```sh
TOKEN=$(curl -sk https://localhost:8443/v1/auth/login \
-d '{"username":"admin","password":"..."}' | jq -r .token)
export MCIAS_TOKEN=$token
mciasctl -server https://localhost:8443 account list
mciasctl account create -username alice -password s3cr3t
mciasctl role set -id $UUID -roles admin
mciasctl token issue -id $SYSTEM_UUID
mciasctl pgcreds set -id $UUID -host db.example.com -port 5432 \
-db mydb -user myuser -password mypassword
```
See `man mciasctl` for the full reference.
---
## Database Maintenance Tool (mciasdb)
```sh
export MCIAS_MASTER_PASSPHRASE=your-passphrase
CONF<<3C>--config /etc/mcias/mcias.conf
mciasdb $CONF schema verify
mciasdb $CONF account list
mciasdb $CONF account set-password --id $UUID
mciasdb $CONF role grant --id $UUID --role admin
mciasdb $CONF prune tokens
mciasdb $CONF audit tail --n 50
mciasdb $CONF audit query --account $UUID --json
```
See `man mciasdb` for the full reference, including the trust model and
safety warnings.
---
## gRPC Interface
Enable the gRPC listener in config:
```toml
[server]
listen_addr = "0.0.0.0:8443"
grpc_addr = "0.0.0.0:9443"
tls_cert = "/etc/mcias/server.crt"
tls_key = "/etc/mcias/server.key"
```
Using mciasgrpcctl:
```sh
export MCIAS_TOKEN=$ADMIN_JWT
mciasgrpcctl -server auth.example.com:9443 -cacert /etc/mcias/server.crt health
mciasgrpcctl account list
```
Using grpcurl:
```sh
grpcurl -cacert /etc/mcias/server.crt \
-H "authorization: Bearer $ADMIN_JWT" \
auth.example.com:9443 \
mcias.v1.AdminService/Health
```
See `man mciasgrpcctl` and [ARCHITECTURE.md](ARCHITECTURE.md) §17.
---
## Deploying with Docker
```sh
make docker
mkdir -p /srv/mcias/config
cp dist/mcias.conf.docker.example /srv/mcias/config/mcias.conf
$EDITOR /srv/mcias/config/mcias.conf
docker run -d \
--name mcias \
-v /srv/mcias/config:/etc/mcias:ro \
-v mcias-data:/data \
-e MCIAS_MASTER_PASSPHRASE=your-passphrase \
-p 8443:8443 \
-p 9443:9443 \
mcias:latest
curl -k https://localhost:8443/v1/health
```
The container runs as uid 10001 (mcias) with no capabilities.
TLS termination happens inside the container.
See `dist/mcias.conf.docker.example` for the config template.
---
## Man Pages
```sh
man mciassrv # server reference
man mciasctl # admin CLI (REST)
man mciasdb # database maintenance tool
man mciasgrpcctl # gRPC admin CLI
```
---
## Security Notes
- JWTs signed with Ed25519 (EdDSA); `alg` header validated before processing
to defeat algorithm confusion attacks.
- Passwords hashed with Argon2id at OWASP 2023 minimum parameters.
- All secret material encrypted at rest with AES-256-GCM using the master key.
- Credential fields never appear in any API response.
- TLS 1.2 minimum protocol version.
See [ARCHITECTURE.md](ARCHITECTURE.md) §2-³3 for the full security model.