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:
277
README.md
277
README.md
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user