# MCIAS — Metacircular Identity and Access System

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), a gRPC API (TLS),
and an HTMX-based web management UI.

See [ARCHITECTURE.md](ARCHITECTURE.md) for the technical design and
[PROJECT_PLAN.md](PROJECT_PLAN.md) for the implementation roadmap.

---

## Quick Start

### Option A: Install from source

**Prerequisites:** Go 1.26+, a C compiler (required by modernc.org/sqlite).

```sh
git clone https://git.wntrmute.dev/mc/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

**Option A: Using the cert tool**

Install the cert tool:
```sh
go install github.com/kisom/cert@latest
```

Create a certificate request configuration file:
```sh
cat > /tmp/request.yaml << EOF
subject:
  common_name: auth.example.com
hosts:
  - auth.example.com
  - localhost
key:
  algo: ecdsa
  size: 521
ca:
  expiry: 87600h  # 10 years
EOF
```

Generate the certificate:
```sh
cert genkey -a ec -s 521 > /srv/mcias/server.key
cert selfsign -p /srv/mcias/server.key -f /tmp/request.yaml > /srv/mcias/server.crt
chmod 0640 /srv/mcias/server.key
chown mcias:mcias /srv/mcias/server.key /srv/mcias/server.crt
rm /tmp/request.yaml
```

**Option B: Using openssl**

```sh
openssl req -x509 -newkey ed25519 -days 3650 \
  -keyout /srv/mcias/server.key \
  -out    /srv/mcias/server.crt \
  -subj   "/CN=auth.example.com" \
  -nodes
chmod 0640 /srv/mcias/server.key
chown mcias:mcias /srv/mcias/server.key /srv/mcias/server.crt
```

### 2. Configure the server

```sh
cp dist/mcias.conf.example /srv/mcias/mcias.toml
$EDITOR /srv/mcias/mcias.toml
chmod 0640 /srv/mcias/mcias.toml
chown mcias:mcias /srv/mcias/mcias.toml
```

Minimum required fields:

```toml
[server]
listen_addr = "0.0.0.0:8443"
tls_cert    = "/srv/mcias/server.crt"
tls_key     = "/srv/mcias/server.key"

[database]
path = "/srv/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 /srv/mcias/env
$EDITOR /srv/mcias/env      # replace the placeholder passphrase
chmod 0640 /srv/mcias/env
chown mcias:mcias /srv/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 /srv/mcias/mcias.toml account create \
  --username admin --type human
mciasdb --config /srv/mcias/mcias.toml account set-password --id <UUID>
mciasdb --config /srv/mcias/mcias.toml role grant --id <UUID> --role admin
```

### 5. Start the server

```sh
# systemd
systemctl enable --now mcias

# manual
MCIAS_MASTER_PASSPHRASE=your-passphrase mciassrv -config /srv/mcias/mcias.toml
```

### 6. Verify

```sh
curl -k https://mcias.metacircular.net: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://mcias.metacircular.net:8443/v1/auth/login \
  -d '{"username":"admin","password":"..."}' | jq -r .token)
export MCIAS_TOKEN=$TOKEN

mciasctl -server https://mcias.metacircular.net:8443 account list
mciasctl account create -username alice          # password prompted interactively
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="--config /srv/mcias/mcias.toml"

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    = "/srv/mcias/server.crt"
tls_key     = "/srv/mcias/server.key"
```

Using mciasgrpcctl:

```sh
export MCIAS_TOKEN=$ADMIN_JWT
mciasgrpcctl -server auth.example.com:9443 -cacert /srv/mcias/server.crt health
mciasgrpcctl account list
```

Using grpcurl:

```sh
grpcurl -cacert /srv/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.

---

## Web Management UI

mciassrv includes a built-in web interface for day-to-day administration.
After starting the server, navigate to `https://mcias.metacircular.net:8443/login` and
log in with an admin account.

The UI provides:
- **Dashboard** — account summary overview
- **Accounts** — list, create, update, delete accounts; manage roles and tags
- **PG Credentials** — view, create, and manage Postgres credential access grants
- **Policies** — create and manage ABAC policy rules
- **Audit** — browse the audit log

Sessions use `HttpOnly; Secure; SameSite=Strict` cookies with CSRF protection.
See [ARCHITECTURE.md](ARCHITECTURE.md) §8 (Web Management UI) for design details.

---

## Deploying with Docker

```sh
make docker

mkdir -p /srv/mcias
cp dist/mcias.conf.docker.example /srv/mcias/mcias.toml
$EDITOR /srv/mcias/mcias.toml

docker run -d \
  --name mcias \
  -v /srv/mcias:/srv/mcias \
  -e MCIAS_MASTER_PASSPHRASE=your-passphrase \
  -p 8443:8443 \
  -p 9443:9443 \
  mcias:latest

curl -k https://mcias.metacircular.net: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.
