Checkpoint: grpc auth fix, issuer list/detail, v2 protos, architecture docs

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
2026-03-15 11:39:13 -07:00
parent d0b1875dbb
commit ad167aed9b
41 changed files with 1080 additions and 219 deletions

View File

@@ -71,9 +71,15 @@ internal/
policy/ Priority-based ACL engine
engine/ Pluggable engine registry & interface
ca/ CA (PKI) engine — X.509 certificate issuance
server/ HTTP server, routes, middleware
server/ REST API HTTP server, routes, middleware
grpcserver/ gRPC server, interceptors, per-service handlers
webserver/ Web UI HTTP server, routes, HTMX handlers
proto/metacrypt/
v1/ Original gRPC proto definitions (generic Execute RPC)
v2/ Typed gRPC proto definitions (per-operation RPCs, Timestamp fields)
gen/metacrypt/v1/ Generated Go gRPC/protobuf code (v1)
web/
templates/ Go HTML templates (layout, init, unseal, login, dashboard)
templates/ Go HTML templates (layout, init, unseal, login, dashboard, PKI)
static/ CSS, HTMX
deploy/ Docker Compose, example configs
```
@@ -432,6 +438,9 @@ Passed as `config` at mount time:
## API Surface
Metacrypt exposes two API surfaces: a JSON REST API and a gRPC API. Both are
kept in sync — every operation available via REST has a corresponding gRPC RPC.
### Seal/Unseal (Unauthenticated)
| Method | Path | Description | Precondition |
@@ -503,24 +512,96 @@ HTTP status codes:
- `412` — service not initialized
- `503` — service is sealed
### gRPC API
Metacrypt also exposes a gRPC API defined in `proto/metacrypt/`. Two API
versions exist:
#### v1 (current implementation)
The v1 API uses a generic `Execute` RPC for all engine operations:
```protobuf
rpc Execute(ExecuteRequest) returns (ExecuteResponse);
message ExecuteRequest {
string mount = 1;
string operation = 2;
string path = 3;
google.protobuf.Struct data = 4; // JSON-like map
}
message ExecuteResponse {
google.protobuf.Struct data = 1; // JSON-like map
}
```
Timestamps are represented as RFC3339 strings within the `Struct` payload.
The `EngineService` also provides `Mount`, `Unmount`, and `ListMounts` RPCs
for engine lifecycle management.
#### v2 (defined, not yet implemented)
The v2 API (`proto/metacrypt/v2/`) replaces the generic `Execute` RPC with
strongly-typed, per-operation RPCs and uses `google.protobuf.Timestamp` for
all time fields. Key changes:
- **`CAService`**: 11 typed RPCs — `ImportRoot`, `GetRoot`, `CreateIssuer`,
`DeleteIssuer`, `ListIssuers`, `GetIssuer`, `GetChain`, `IssueCert`,
`GetCert`, `ListCerts`, `RenewCert`.
- **`EngineService`**: Retains `Mount`, `Unmount`, `ListMounts`; drops the
generic `Execute` RPC. `MountRequest.config` is `map<string, string>`
instead of `google.protobuf.Struct`.
- **Timestamps**: All `issued_at` / `expires_at` fields use
`google.protobuf.Timestamp` instead of RFC3339 strings.
- **Message types**: `CertRecord` (full certificate data) and `CertSummary`
(lightweight, for list responses) replace the generic struct maps.
- **`ACMEService`** and **`AuthService`**: String timestamps replaced by
`google.protobuf.Timestamp`.
The v2 proto definitions pass `buf lint` with no warnings. Server-side
implementation of v2 is planned as a future milestone.
#### gRPC Interceptors (v1)
The gRPC server (`internal/grpcserver/`) uses three interceptor maps to gate
access:
| Interceptor map | Effect |
|-----------------------|-----------------------------------------------------|
| `sealRequiredMethods` | Returns `UNAVAILABLE` if the barrier is sealed |
| `authRequiredMethods` | Validates MCIAS bearer token; populates caller info |
| `adminRequiredMethods`| Requires `IsAdmin == true` on the caller |
All three maps include the `Execute` RPC, ensuring engine operations are
always authenticated and gated on unseal state.
---
## Web Interface
Metacrypt includes an HTMX-powered web UI for basic operations:
| Route | Purpose |
|---------------|--------------------------------------------------|
| `/` | Redirects based on service state |
| `/init` | Password setup form (first-time only) |
| `/unseal` | Password entry to unseal |
| `/login` | MCIAS login form (username, password, TOTP) |
| `/dashboard` | Engine mounts, service state, admin controls |
| Route | Purpose |
|--------------------------|-------------------------------------------------------|
| `/` | Redirects based on service state |
| `/init` | Password setup form (first-time only) |
| `/unseal` | Password entry to unseal |
| `/login` | MCIAS login form (username, password, TOTP) |
| `/dashboard` | Engine mounts, service state, admin controls |
| `/pki` | PKI overview: list issuers, download CA/issuer PEMs |
| `/pki/issuer/{name}` | Issuer detail: certificates issued by that issuer |
The dashboard shows mounted engines, the service state, and (for admins) a seal
button. Templates use Go's `html/template` with a shared layout. HTMX provides
form submission without full page reloads.
The PKI pages communicate with the backend via the internal gRPC client
(`internal/webserver/client.go`), which wraps the v1 gRPC `Execute` RPC.
The issuer detail page supports filtering certificates by common name
(case-insensitive substring match) and sorting by common name (default) or
expiry date.
---
## Database Schema
@@ -683,7 +764,9 @@ closing connections before exit.
### Planned Capabilities
- **gRPC API** — In addition to the JSON REST API (config field already reserved)
- **gRPC v2 server implementation** — The v2 typed proto definitions are
complete; the server-side handlers and generated Go code remain to be
implemented
- **Post-quantum readiness** — Hybrid key exchange (ML-KEM + ECDH); the
versioned ciphertext format and engine interface are designed for algorithm
agility