Add ACME (RFC 8555) server and Go client library
Implements full ACME protocol support in Metacrypt:
- internal/acme: core types, JWS verification (ES256/384/512 + RS256),
nonce store, per-mount handler, all RFC 8555 protocol endpoints,
HTTP-01 and DNS-01 challenge validation, EAB management
- internal/server/acme.go: management REST routes (EAB create, config,
list accounts/orders) + ACME protocol route dispatch
- proto/metacrypt/v1/acme.proto: ACMEService (CreateEAB, SetConfig,
ListAccounts, ListOrders) — protocol endpoints are HTTP-only per RFC
- clients/go: new Go module with MCIAS-auth bootstrap, ACME account
registration, certificate issuance/renewal, HTTP-01 and DNS-01
challenge providers
- .claude/launch.json: dev server configuration
EAB is required for all account creation; MCIAS-authenticated users
obtain a single-use KID + HMAC-SHA256 key via POST /v1/acme/{mount}/eab.
This commit is contained in:
83
proto/metacrypt/v1/acme.proto
Normal file
83
proto/metacrypt/v1/acme.proto
Normal file
@@ -0,0 +1,83 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package metacrypt.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/metacrypt/gen/metacrypt/v1;metacryptv1";
|
||||
|
||||
// ACMEService provides authenticated management of ACME state.
|
||||
// These RPCs correspond to the REST management endpoints at /v1/acme/{mount}/.
|
||||
// The ACME protocol endpoints themselves (/acme/{mount}/...) are HTTP-only
|
||||
// per RFC 8555 and have no gRPC equivalents.
|
||||
service ACMEService {
|
||||
// CreateEAB creates External Account Binding credentials for the
|
||||
// authenticated MCIAS user. The returned kid and hmac_key are used
|
||||
// with any RFC 8555-compliant ACME client to register an account.
|
||||
rpc CreateEAB(CreateEABRequest) returns (CreateEABResponse);
|
||||
|
||||
// SetConfig sets the ACME configuration for a CA mount.
|
||||
// Currently configures the default issuer used for ACME certificate issuance.
|
||||
rpc SetConfig(SetACMEConfigRequest) returns (SetACMEConfigResponse);
|
||||
|
||||
// ListAccounts returns all ACME accounts for a CA mount. Admin only.
|
||||
rpc ListAccounts(ListACMEAccountsRequest) returns (ListACMEAccountsResponse);
|
||||
|
||||
// ListOrders returns all ACME orders for a CA mount. Admin only.
|
||||
rpc ListOrders(ListACMEOrdersRequest) returns (ListACMEOrdersResponse);
|
||||
}
|
||||
|
||||
message CreateEABRequest {
|
||||
string mount = 1;
|
||||
}
|
||||
|
||||
message CreateEABResponse {
|
||||
// kid is the key identifier to pass to the ACME client.
|
||||
string kid = 1;
|
||||
// hmac_key is the raw 32-byte HMAC-SHA256 key.
|
||||
// Base64url-encode this value when configuring an ACME client.
|
||||
bytes hmac_key = 2;
|
||||
}
|
||||
|
||||
message SetACMEConfigRequest {
|
||||
string mount = 1;
|
||||
// default_issuer is the name of the CA issuer to use for ACME certificates.
|
||||
// The issuer must already exist on the CA mount.
|
||||
string default_issuer = 2;
|
||||
}
|
||||
|
||||
message SetACMEConfigResponse {
|
||||
bool ok = 1;
|
||||
}
|
||||
|
||||
message ListACMEAccountsRequest {
|
||||
string mount = 1;
|
||||
}
|
||||
|
||||
message ListACMEAccountsResponse {
|
||||
repeated ACMEAccount accounts = 1;
|
||||
}
|
||||
|
||||
message ACMEAccount {
|
||||
string id = 1;
|
||||
string status = 2;
|
||||
repeated string contact = 3;
|
||||
string mcias_username = 4;
|
||||
string created_at = 5;
|
||||
}
|
||||
|
||||
message ListACMEOrdersRequest {
|
||||
string mount = 1;
|
||||
}
|
||||
|
||||
message ListACMEOrdersResponse {
|
||||
repeated ACMEOrder orders = 1;
|
||||
}
|
||||
|
||||
message ACMEOrder {
|
||||
string id = 1;
|
||||
string account_id = 2;
|
||||
string status = 3;
|
||||
// identifiers are in "type:value" format, e.g. "dns:example.com".
|
||||
repeated string identifiers = 4;
|
||||
string created_at = 5;
|
||||
string expires_at = 6;
|
||||
}
|
||||
Reference in New Issue
Block a user