Phase 10: gRPC admin API with interceptor chain
Proto definitions for 4 services (RegistryService, PolicyService, AuditService, AdminService) with hand-written Go stubs using JSON codec until protobuf tooling is available. Interceptor chain: logging (method, peer IP, duration, never logs auth metadata) → auth (bearer token via MCIAS, Health bypasses) → admin (role check for GC, policy, delete, audit RPCs). All RPCs share business logic with REST handlers via internal/db and internal/gc packages. TLS 1.3 minimum on gRPC listener. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
proto/mcr/v1/admin.proto
Normal file
15
proto/mcr/v1/admin.proto
Normal file
@@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
service AdminService {
|
||||
rpc Health(HealthRequest) returns (HealthResponse);
|
||||
}
|
||||
|
||||
message HealthRequest {}
|
||||
|
||||
message HealthResponse {
|
||||
string status = 1;
|
||||
}
|
||||
35
proto/mcr/v1/audit.proto
Normal file
35
proto/mcr/v1/audit.proto
Normal file
@@ -0,0 +1,35 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
service AuditService {
|
||||
rpc ListAuditEvents(ListAuditEventsRequest) returns (ListAuditEventsResponse);
|
||||
}
|
||||
|
||||
message AuditEvent {
|
||||
int64 id = 1;
|
||||
string event_time = 2;
|
||||
string event_type = 3;
|
||||
string actor_id = 4;
|
||||
string repository = 5;
|
||||
string digest = 6;
|
||||
string ip_address = 7;
|
||||
map<string, string> details = 8;
|
||||
}
|
||||
|
||||
message ListAuditEventsRequest {
|
||||
PaginationRequest pagination = 1;
|
||||
string event_type = 2;
|
||||
string actor_id = 3;
|
||||
string repository = 4;
|
||||
string since = 5;
|
||||
string until = 6;
|
||||
}
|
||||
|
||||
message ListAuditEventsResponse {
|
||||
repeated AuditEvent events = 1;
|
||||
}
|
||||
11
proto/mcr/v1/common.proto
Normal file
11
proto/mcr/v1/common.proto
Normal file
@@ -0,0 +1,11 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
// Pagination controls for list RPCs.
|
||||
message PaginationRequest {
|
||||
int32 limit = 1;
|
||||
int32 offset = 2;
|
||||
}
|
||||
76
proto/mcr/v1/policy.proto
Normal file
76
proto/mcr/v1/policy.proto
Normal file
@@ -0,0 +1,76 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
service PolicyService {
|
||||
rpc ListPolicyRules(ListPolicyRulesRequest) returns (ListPolicyRulesResponse);
|
||||
rpc CreatePolicyRule(CreatePolicyRuleRequest) returns (PolicyRule);
|
||||
rpc GetPolicyRule(GetPolicyRuleRequest) returns (PolicyRule);
|
||||
rpc UpdatePolicyRule(UpdatePolicyRuleRequest) returns (PolicyRule);
|
||||
rpc DeletePolicyRule(DeletePolicyRuleRequest) returns (DeletePolicyRuleResponse);
|
||||
}
|
||||
|
||||
message PolicyRule {
|
||||
int64 id = 1;
|
||||
int32 priority = 2;
|
||||
string description = 3;
|
||||
string effect = 4;
|
||||
repeated string roles = 5;
|
||||
repeated string account_types = 6;
|
||||
string subject_uuid = 7;
|
||||
repeated string actions = 8;
|
||||
repeated string repositories = 9;
|
||||
bool enabled = 10;
|
||||
string created_by = 11;
|
||||
string created_at = 12;
|
||||
string updated_at = 13;
|
||||
}
|
||||
|
||||
message ListPolicyRulesRequest {
|
||||
PaginationRequest pagination = 1;
|
||||
}
|
||||
|
||||
message ListPolicyRulesResponse {
|
||||
repeated PolicyRule rules = 1;
|
||||
}
|
||||
|
||||
message CreatePolicyRuleRequest {
|
||||
int32 priority = 1;
|
||||
string description = 2;
|
||||
string effect = 3;
|
||||
repeated string roles = 4;
|
||||
repeated string account_types = 5;
|
||||
string subject_uuid = 6;
|
||||
repeated string actions = 7;
|
||||
repeated string repositories = 8;
|
||||
bool enabled = 9;
|
||||
}
|
||||
|
||||
message GetPolicyRuleRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message UpdatePolicyRuleRequest {
|
||||
int64 id = 1;
|
||||
int32 priority = 2;
|
||||
string description = 3;
|
||||
string effect = 4;
|
||||
repeated string roles = 5;
|
||||
repeated string account_types = 6;
|
||||
string subject_uuid = 7;
|
||||
repeated string actions = 8;
|
||||
repeated string repositories = 9;
|
||||
bool enabled = 10;
|
||||
// Field mask for partial updates — only fields listed here are applied.
|
||||
repeated string update_mask = 11;
|
||||
}
|
||||
|
||||
message DeletePolicyRuleRequest {
|
||||
int64 id = 1;
|
||||
}
|
||||
|
||||
message DeletePolicyRuleResponse {}
|
||||
81
proto/mcr/v1/registry.proto
Normal file
81
proto/mcr/v1/registry.proto
Normal file
@@ -0,0 +1,81 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mcr.v1;
|
||||
|
||||
option go_package = "git.wntrmute.dev/kyle/mcr/gen/mcr/v1;mcrv1";
|
||||
|
||||
import "mcr/v1/common.proto";
|
||||
|
||||
service RegistryService {
|
||||
rpc ListRepositories(ListRepositoriesRequest) returns (ListRepositoriesResponse);
|
||||
rpc GetRepository(GetRepositoryRequest) returns (GetRepositoryResponse);
|
||||
rpc DeleteRepository(DeleteRepositoryRequest) returns (DeleteRepositoryResponse);
|
||||
rpc GarbageCollect(GarbageCollectRequest) returns (GarbageCollectResponse);
|
||||
rpc GetGCStatus(GetGCStatusRequest) returns (GetGCStatusResponse);
|
||||
}
|
||||
|
||||
message RepositoryMetadata {
|
||||
string name = 1;
|
||||
int32 tag_count = 2;
|
||||
int32 manifest_count = 3;
|
||||
int64 total_size = 4;
|
||||
string created_at = 5;
|
||||
}
|
||||
|
||||
message TagInfo {
|
||||
string name = 1;
|
||||
string digest = 2;
|
||||
}
|
||||
|
||||
message ManifestInfo {
|
||||
string digest = 1;
|
||||
string media_type = 2;
|
||||
int64 size = 3;
|
||||
string created_at = 4;
|
||||
}
|
||||
|
||||
message ListRepositoriesRequest {
|
||||
PaginationRequest pagination = 1;
|
||||
}
|
||||
|
||||
message ListRepositoriesResponse {
|
||||
repeated RepositoryMetadata repositories = 1;
|
||||
}
|
||||
|
||||
message GetRepositoryRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message GetRepositoryResponse {
|
||||
string name = 1;
|
||||
repeated TagInfo tags = 2;
|
||||
repeated ManifestInfo manifests = 3;
|
||||
int64 total_size = 4;
|
||||
string created_at = 5;
|
||||
}
|
||||
|
||||
message DeleteRepositoryRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message DeleteRepositoryResponse {}
|
||||
|
||||
message GarbageCollectRequest {}
|
||||
|
||||
message GarbageCollectResponse {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message GetGCStatusRequest {}
|
||||
|
||||
message GCLastRun {
|
||||
string started_at = 1;
|
||||
string completed_at = 2;
|
||||
int32 blobs_removed = 3;
|
||||
int64 bytes_freed = 4;
|
||||
}
|
||||
|
||||
message GetGCStatusResponse {
|
||||
bool running = 1;
|
||||
GCLastRun last_run = 2;
|
||||
}
|
||||
Reference in New Issue
Block a user