Harden deployment and fix PEN-01

- Fix Bearer token extraction to validate prefix (PEN-01)
- Add TestExtractBearerFromRequest covering PEN-01 edge cases
- Fix flaky TestRenewToken timing (2s → 4s lifetime)
- Move default config/install paths to /srv/mcias
- Add RUNBOOK.md for operational procedures
- Update AUDIT.md with penetration test round 4

Security: extractBearerFromRequest now uses case-insensitive prefix
validation instead of fixed-offset slicing, rejecting non-Bearer
Authorization schemes that were previously accepted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-14 22:33:24 -07:00
parent 2a85d4bf2b
commit 1121b7d4fd
14 changed files with 774 additions and 117 deletions

View File

@@ -64,10 +64,10 @@ EOF
Generate the certificate:
```sh
cert genkey -a ec -s 521 > /etc/mcias/server.key
cert selfsign -p /etc/mcias/server.key -f /tmp/request.yaml > /etc/mcias/server.crt
chmod 0640 /etc/mcias/server.key
chown root:mcias /etc/mcias/server.key
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
```
@@ -75,21 +75,21 @@ rm /tmp/request.yaml
```sh
openssl req -x509 -newkey ed25519 -days 3650 \
-keyout /etc/mcias/server.key \
-out /etc/mcias/server.crt \
-keyout /srv/mcias/server.key \
-out /srv/mcias/server.crt \
-subj "/CN=auth.example.com" \
-nodes
chmod 0640 /etc/mcias/server.key
chown root:mcias /etc/mcias/server.key
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 /etc/mcias/mcias.conf
$EDITOR /etc/mcias/mcias.conf
chmod 0640 /etc/mcias/mcias.conf
chown root:mcias /etc/mcias/mcias.conf
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:
@@ -97,11 +97,11 @@ Minimum required fields:
```toml
[server]
listen_addr = "0.0.0.0:8443"
tls_cert = "/etc/mcias/server.crt"
tls_key = "/etc/mcias/server.key"
tls_cert = "/srv/mcias/server.crt"
tls_key = "/srv/mcias/server.key"
[database]
path = "/var/lib/mcias/mcias.db"
path = "/srv/mcias/mcias.db"
[tokens]
issuer = "https://auth.example.com"
@@ -116,10 +116,10 @@ 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
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.
@@ -130,10 +130,10 @@ chown root:mcias /etc/mcias/env
```sh
export MCIAS_MASTER_PASSPHRASE=your-passphrase
mciasdb --config /etc/mcias/mcias.conf account create \
mciasdb --config /srv/mcias/mcias.toml 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
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
@@ -143,7 +143,7 @@ mciasdb --config /etc/mcias/mcias.conf role grant --id <UUID> --role admin
systemctl enable --now mcias
# manual
MCIAS_MASTER_PASSPHRASE=your-passphrase mciassrv -config /etc/mcias/mcias.conf
MCIAS_MASTER_PASSPHRASE=your-passphrase mciassrv -config /srv/mcias/mcias.toml
```
### 6. Verify
@@ -193,7 +193,7 @@ See `man mciasctl` for the full reference.
```sh
export MCIAS_MASTER_PASSPHRASE=your-passphrase
CONF="--config /etc/mcias/mcias.conf"
CONF="--config /srv/mcias/mcias.toml"
mciasdb $CONF schema verify
mciasdb $CONF account list
@@ -217,22 +217,22 @@ Enable the gRPC listener in config:
[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"
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 /etc/mcias/server.crt health
mciasgrpcctl -server auth.example.com:9443 -cacert /srv/mcias/server.crt health
mciasgrpcctl account list
```
Using grpcurl:
```sh
grpcurl -cacert /etc/mcias/server.crt \
grpcurl -cacert /srv/mcias/server.crt \
-H "authorization: Bearer $ADMIN_JWT" \
auth.example.com:9443 \
mcias.v1.AdminService/Health
@@ -265,14 +265,13 @@ See [ARCHITECTURE.md](ARCHITECTURE.md) §8 (Web Management UI) for design detail
```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
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/config:/etc/mcias:ro \
-v mcias-data:/data \
-v /srv/mcias:/srv/mcias \
-e MCIAS_MASTER_PASSPHRASE=your-passphrase \
-p 8443:8443 \
-p 9443:9443 \