detached 4269eaf

feat(proto): commit signature verification and trusted keys (#20)

commit
4269eaf418f570f2486a5005717ff5dae200e427
author
brice · · 2026-10-18 18:03 UTC
committer
bnema · · 2026-10-18 18:03 UTC
parent
e06a09c
signature
SSH UnverifiedSHA256:VOCA5lYARHcbKDZ7GhTV45VmcjWnJ6ZQIBazj17LivA The key is unknown
refs
tag: v0.6.0
7 files · +1099 -9
M README.md +1 -0
@@ -41,6 +41,7 @@ Status: early development.
4141 | `SecretService`, `VariableService`, `EnvironmentService` | CI settings |
4242 | `ArtifactService` | CI artifacts, for people |
4343 | `JobArtifactService` | CI artifacts v4, for runners |
44+| `TrustedKeyService` | SSH and OpenPGP keys commit signatures are checked against |
4445
4546 Every RPC: [docs/services.md](docs/services.md).
4647
@@ -41,6 +41,7 @@ Status: early development.
41 | `SecretService`, `VariableService`, `EnvironmentService` | CI settings |41 | `SecretService`, `VariableService`, `EnvironmentService` | CI settings |
42 | `ArtifactService` | CI artifacts, for people |42 | `ArtifactService` | CI artifacts, for people |
43 | `JobArtifactService` | CI artifacts v4, for runners |43 | `JobArtifactService` | CI artifacts v4, for runners |
44+| `TrustedKeyService` | SSH and OpenPGP keys commit signatures are checked against |
44 45
45 Every RPC: [docs/services.md](docs/services.md).46 Every RPC: [docs/services.md](docs/services.md).
46 47
M docs/services.md +1 -0
@@ -9,6 +9,7 @@
99 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |
1010 | `EventService` | `Watch` (streamed, resumable) |
1111 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |
12+| `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) |
1213 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |
1314 | `RunnerService` | `RegisterRunner`, `FetchJob` (long poll), `UpdateJob`, `AppendLog` (offset-idempotent), `Heartbeat`, `WatchJob` (cancel requests, streamed), `CompleteJob` (idempotent), `ResolveActions`, `UploadSummary` |
1415 | `SecretService` | `SetSecret`, `ListSecrets` (names only), `DeleteSecret`. Scopes: instance, repository, environment |
@@ -9,6 +9,7 @@
9 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |9 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |
10 | `EventService` | `Watch` (streamed, resumable) |10 | `EventService` | `Watch` (streamed, resumable) |
11 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |11 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |
12+| `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) |
12 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |13 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |
13 | `RunnerService` | `RegisterRunner`, `FetchJob` (long poll), `UpdateJob`, `AppendLog` (offset-idempotent), `Heartbeat`, `WatchJob` (cancel requests, streamed), `CompleteJob` (idempotent), `ResolveActions`, `UploadSummary` |14 | `RunnerService` | `RegisterRunner`, `FetchJob` (long poll), `UpdateJob`, `AppendLog` (offset-idempotent), `Heartbeat`, `WatchJob` (cancel requests, streamed), `CompleteJob` (idempotent), `ResolveActions`, `UploadSummary` |
14 | `SecretService` | `SetSecret`, `ListSecrets` (names only), `DeleteSecret`. Scopes: instance, repository, environment |15 | `SecretService` | `SetSecret`, `ListSecrets` (names only), `DeleteSecret`. Scopes: instance, repository, environment |
A gen/ermite/ermiteconnect/signature.connect.go +183 -0
@@ -0,0 +1,183 @@
1+// SPDX-License-Identifier: MIT
2+
3+// Code generated by protoc-gen-connect-go. DO NOT EDIT.
4+//
5+// Source: ermite/signature.proto
6+
7+package ermiteconnect
8+
9+import (
10+ ermite "bnema.dev/ermite-api/gen/ermite"
11+ connect "connectrpc.com/connect"
12+ context "context"
13+ errors "errors"
14+ http "net/http"
15+ strings "strings"
16+)
17+
18+// This is a compile-time assertion to ensure that this generated file and the connect package are
19+// compatible. If you get a compiler error that this constant is not defined, this code was
20+// generated with a version of connect newer than the one compiled into your binary. You can fix the
21+// problem by either regenerating this code with an older version of connect or updating the connect
22+// version compiled into your binary.
23+const _ = connect.IsAtLeastVersion1_13_0
24+
25+const (
26+ // TrustedKeyServiceName is the fully-qualified name of the TrustedKeyService service.
27+ TrustedKeyServiceName = "ermite.TrustedKeyService"
28+)
29+
30+// These constants are the fully-qualified names of the RPCs defined in this package. They're
31+// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
32+//
33+// Note that these are different from the fully-qualified method names used by
34+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
35+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
36+// period.
37+const (
38+ // TrustedKeyServiceListTrustedKeysProcedure is the fully-qualified name of the TrustedKeyService's
39+ // ListTrustedKeys RPC.
40+ TrustedKeyServiceListTrustedKeysProcedure = "/ermite.TrustedKeyService/ListTrustedKeys"
41+ // TrustedKeyServiceAddTrustedKeyProcedure is the fully-qualified name of the TrustedKeyService's
42+ // AddTrustedKey RPC.
43+ TrustedKeyServiceAddTrustedKeyProcedure = "/ermite.TrustedKeyService/AddTrustedKey"
44+ // TrustedKeyServiceRemoveTrustedKeyProcedure is the fully-qualified name of the TrustedKeyService's
45+ // RemoveTrustedKey RPC.
46+ TrustedKeyServiceRemoveTrustedKeyProcedure = "/ermite.TrustedKeyService/RemoveTrustedKey"
47+)
48+
49+// TrustedKeyServiceClient is a client for the ermite.TrustedKeyService service.
50+type TrustedKeyServiceClient interface {
51+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
52+ // caller may.
53+ ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error)
54+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
55+ // does not parse, a private key, no or too many emails; already_exists for
56+ // a key already listed; resource_exhausted beyond 100 keys.
57+ AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error)
58+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
59+ // failed_precondition for the builtin key.
60+ RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error)
61+}
62+
63+// NewTrustedKeyServiceClient constructs a client for the ermite.TrustedKeyService service. By
64+// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
65+// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
66+// connect.WithGRPC() or connect.WithGRPCWeb() options.
67+//
68+// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
69+// http://api.acme.com or https://acme.com/grpc).
70+func NewTrustedKeyServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) TrustedKeyServiceClient {
71+ baseURL = strings.TrimRight(baseURL, "/")
72+ trustedKeyServiceMethods := ermite.File_ermite_signature_proto.Services().ByName("TrustedKeyService").Methods()
73+ return &trustedKeyServiceClient{
74+ listTrustedKeys: connect.NewClient[ermite.ListTrustedKeysRequest, ermite.ListTrustedKeysResponse](
75+ httpClient,
76+ baseURL+TrustedKeyServiceListTrustedKeysProcedure,
77+ connect.WithSchema(trustedKeyServiceMethods.ByName("ListTrustedKeys")),
78+ connect.WithClientOptions(opts...),
79+ ),
80+ addTrustedKey: connect.NewClient[ermite.AddTrustedKeyRequest, ermite.AddTrustedKeyResponse](
81+ httpClient,
82+ baseURL+TrustedKeyServiceAddTrustedKeyProcedure,
83+ connect.WithSchema(trustedKeyServiceMethods.ByName("AddTrustedKey")),
84+ connect.WithClientOptions(opts...),
85+ ),
86+ removeTrustedKey: connect.NewClient[ermite.RemoveTrustedKeyRequest, ermite.RemoveTrustedKeyResponse](
87+ httpClient,
88+ baseURL+TrustedKeyServiceRemoveTrustedKeyProcedure,
89+ connect.WithSchema(trustedKeyServiceMethods.ByName("RemoveTrustedKey")),
90+ connect.WithClientOptions(opts...),
91+ ),
92+ }
93+}
94+
95+// trustedKeyServiceClient implements TrustedKeyServiceClient.
96+type trustedKeyServiceClient struct {
97+ listTrustedKeys *connect.Client[ermite.ListTrustedKeysRequest, ermite.ListTrustedKeysResponse]
98+ addTrustedKey *connect.Client[ermite.AddTrustedKeyRequest, ermite.AddTrustedKeyResponse]
99+ removeTrustedKey *connect.Client[ermite.RemoveTrustedKeyRequest, ermite.RemoveTrustedKeyResponse]
100+}
101+
102+// ListTrustedKeys calls ermite.TrustedKeyService.ListTrustedKeys.
103+func (c *trustedKeyServiceClient) ListTrustedKeys(ctx context.Context, req *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error) {
104+ return c.listTrustedKeys.CallUnary(ctx, req)
105+}
106+
107+// AddTrustedKey calls ermite.TrustedKeyService.AddTrustedKey.
108+func (c *trustedKeyServiceClient) AddTrustedKey(ctx context.Context, req *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error) {
109+ return c.addTrustedKey.CallUnary(ctx, req)
110+}
111+
112+// RemoveTrustedKey calls ermite.TrustedKeyService.RemoveTrustedKey.
113+func (c *trustedKeyServiceClient) RemoveTrustedKey(ctx context.Context, req *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error) {
114+ return c.removeTrustedKey.CallUnary(ctx, req)
115+}
116+
117+// TrustedKeyServiceHandler is an implementation of the ermite.TrustedKeyService service.
118+type TrustedKeyServiceHandler interface {
119+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
120+ // caller may.
121+ ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error)
122+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
123+ // does not parse, a private key, no or too many emails; already_exists for
124+ // a key already listed; resource_exhausted beyond 100 keys.
125+ AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error)
126+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
127+ // failed_precondition for the builtin key.
128+ RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error)
129+}
130+
131+// NewTrustedKeyServiceHandler builds an HTTP handler from the service implementation. It returns
132+// the path on which to mount the handler and the handler itself.
133+//
134+// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
135+// and JSON codecs. They also support gzip compression.
136+func NewTrustedKeyServiceHandler(svc TrustedKeyServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
137+ trustedKeyServiceMethods := ermite.File_ermite_signature_proto.Services().ByName("TrustedKeyService").Methods()
138+ trustedKeyServiceListTrustedKeysHandler := connect.NewUnaryHandler(
139+ TrustedKeyServiceListTrustedKeysProcedure,
140+ svc.ListTrustedKeys,
141+ connect.WithSchema(trustedKeyServiceMethods.ByName("ListTrustedKeys")),
142+ connect.WithHandlerOptions(opts...),
143+ )
144+ trustedKeyServiceAddTrustedKeyHandler := connect.NewUnaryHandler(
145+ TrustedKeyServiceAddTrustedKeyProcedure,
146+ svc.AddTrustedKey,
147+ connect.WithSchema(trustedKeyServiceMethods.ByName("AddTrustedKey")),
148+ connect.WithHandlerOptions(opts...),
149+ )
150+ trustedKeyServiceRemoveTrustedKeyHandler := connect.NewUnaryHandler(
151+ TrustedKeyServiceRemoveTrustedKeyProcedure,
152+ svc.RemoveTrustedKey,
153+ connect.WithSchema(trustedKeyServiceMethods.ByName("RemoveTrustedKey")),
154+ connect.WithHandlerOptions(opts...),
155+ )
156+ return "/ermite.TrustedKeyService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
157+ switch r.URL.Path {
158+ case TrustedKeyServiceListTrustedKeysProcedure:
159+ trustedKeyServiceListTrustedKeysHandler.ServeHTTP(w, r)
160+ case TrustedKeyServiceAddTrustedKeyProcedure:
161+ trustedKeyServiceAddTrustedKeyHandler.ServeHTTP(w, r)
162+ case TrustedKeyServiceRemoveTrustedKeyProcedure:
163+ trustedKeyServiceRemoveTrustedKeyHandler.ServeHTTP(w, r)
164+ default:
165+ http.NotFound(w, r)
166+ }
167+ })
168+}
169+
170+// UnimplementedTrustedKeyServiceHandler returns CodeUnimplemented from all methods.
171+type UnimplementedTrustedKeyServiceHandler struct{}
172+
173+func (UnimplementedTrustedKeyServiceHandler) ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error) {
174+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.ListTrustedKeys is not implemented"))
175+}
176+
177+func (UnimplementedTrustedKeyServiceHandler) AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error) {
178+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.AddTrustedKey is not implemented"))
179+}
180+
181+func (UnimplementedTrustedKeyServiceHandler) RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error) {
182+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.RemoveTrustedKey is not implemented"))
183+}
@@ -0,0 +1,183 @@
1+// SPDX-License-Identifier: MIT
2+
3+// Code generated by protoc-gen-connect-go. DO NOT EDIT.
4+//
5+// Source: ermite/signature.proto
6+
7+package ermiteconnect
8+
9+import (
10+ ermite "bnema.dev/ermite-api/gen/ermite"
11+ connect "connectrpc.com/connect"
12+ context "context"
13+ errors "errors"
14+ http "net/http"
15+ strings "strings"
16+)
17+
18+// This is a compile-time assertion to ensure that this generated file and the connect package are
19+// compatible. If you get a compiler error that this constant is not defined, this code was
20+// generated with a version of connect newer than the one compiled into your binary. You can fix the
21+// problem by either regenerating this code with an older version of connect or updating the connect
22+// version compiled into your binary.
23+const _ = connect.IsAtLeastVersion1_13_0
24+
25+const (
26+ // TrustedKeyServiceName is the fully-qualified name of the TrustedKeyService service.
27+ TrustedKeyServiceName = "ermite.TrustedKeyService"
28+)
29+
30+// These constants are the fully-qualified names of the RPCs defined in this package. They're
31+// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
32+//
33+// Note that these are different from the fully-qualified method names used by
34+// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
35+// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
36+// period.
37+const (
38+ // TrustedKeyServiceListTrustedKeysProcedure is the fully-qualified name of the TrustedKeyService's
39+ // ListTrustedKeys RPC.
40+ TrustedKeyServiceListTrustedKeysProcedure = "/ermite.TrustedKeyService/ListTrustedKeys"
41+ // TrustedKeyServiceAddTrustedKeyProcedure is the fully-qualified name of the TrustedKeyService's
42+ // AddTrustedKey RPC.
43+ TrustedKeyServiceAddTrustedKeyProcedure = "/ermite.TrustedKeyService/AddTrustedKey"
44+ // TrustedKeyServiceRemoveTrustedKeyProcedure is the fully-qualified name of the TrustedKeyService's
45+ // RemoveTrustedKey RPC.
46+ TrustedKeyServiceRemoveTrustedKeyProcedure = "/ermite.TrustedKeyService/RemoveTrustedKey"
47+)
48+
49+// TrustedKeyServiceClient is a client for the ermite.TrustedKeyService service.
50+type TrustedKeyServiceClient interface {
51+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
52+ // caller may.
53+ ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error)
54+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
55+ // does not parse, a private key, no or too many emails; already_exists for
56+ // a key already listed; resource_exhausted beyond 100 keys.
57+ AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error)
58+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
59+ // failed_precondition for the builtin key.
60+ RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error)
61+}
62+
63+// NewTrustedKeyServiceClient constructs a client for the ermite.TrustedKeyService service. By
64+// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
65+// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
66+// connect.WithGRPC() or connect.WithGRPCWeb() options.
67+//
68+// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
69+// http://api.acme.com or https://acme.com/grpc).
70+func NewTrustedKeyServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) TrustedKeyServiceClient {
71+ baseURL = strings.TrimRight(baseURL, "/")
72+ trustedKeyServiceMethods := ermite.File_ermite_signature_proto.Services().ByName("TrustedKeyService").Methods()
73+ return &trustedKeyServiceClient{
74+ listTrustedKeys: connect.NewClient[ermite.ListTrustedKeysRequest, ermite.ListTrustedKeysResponse](
75+ httpClient,
76+ baseURL+TrustedKeyServiceListTrustedKeysProcedure,
77+ connect.WithSchema(trustedKeyServiceMethods.ByName("ListTrustedKeys")),
78+ connect.WithClientOptions(opts...),
79+ ),
80+ addTrustedKey: connect.NewClient[ermite.AddTrustedKeyRequest, ermite.AddTrustedKeyResponse](
81+ httpClient,
82+ baseURL+TrustedKeyServiceAddTrustedKeyProcedure,
83+ connect.WithSchema(trustedKeyServiceMethods.ByName("AddTrustedKey")),
84+ connect.WithClientOptions(opts...),
85+ ),
86+ removeTrustedKey: connect.NewClient[ermite.RemoveTrustedKeyRequest, ermite.RemoveTrustedKeyResponse](
87+ httpClient,
88+ baseURL+TrustedKeyServiceRemoveTrustedKeyProcedure,
89+ connect.WithSchema(trustedKeyServiceMethods.ByName("RemoveTrustedKey")),
90+ connect.WithClientOptions(opts...),
91+ ),
92+ }
93+}
94+
95+// trustedKeyServiceClient implements TrustedKeyServiceClient.
96+type trustedKeyServiceClient struct {
97+ listTrustedKeys *connect.Client[ermite.ListTrustedKeysRequest, ermite.ListTrustedKeysResponse]
98+ addTrustedKey *connect.Client[ermite.AddTrustedKeyRequest, ermite.AddTrustedKeyResponse]
99+ removeTrustedKey *connect.Client[ermite.RemoveTrustedKeyRequest, ermite.RemoveTrustedKeyResponse]
100+}
101+
102+// ListTrustedKeys calls ermite.TrustedKeyService.ListTrustedKeys.
103+func (c *trustedKeyServiceClient) ListTrustedKeys(ctx context.Context, req *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error) {
104+ return c.listTrustedKeys.CallUnary(ctx, req)
105+}
106+
107+// AddTrustedKey calls ermite.TrustedKeyService.AddTrustedKey.
108+func (c *trustedKeyServiceClient) AddTrustedKey(ctx context.Context, req *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error) {
109+ return c.addTrustedKey.CallUnary(ctx, req)
110+}
111+
112+// RemoveTrustedKey calls ermite.TrustedKeyService.RemoveTrustedKey.
113+func (c *trustedKeyServiceClient) RemoveTrustedKey(ctx context.Context, req *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error) {
114+ return c.removeTrustedKey.CallUnary(ctx, req)
115+}
116+
117+// TrustedKeyServiceHandler is an implementation of the ermite.TrustedKeyService service.
118+type TrustedKeyServiceHandler interface {
119+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
120+ // caller may.
121+ ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error)
122+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
123+ // does not parse, a private key, no or too many emails; already_exists for
124+ // a key already listed; resource_exhausted beyond 100 keys.
125+ AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error)
126+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
127+ // failed_precondition for the builtin key.
128+ RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error)
129+}
130+
131+// NewTrustedKeyServiceHandler builds an HTTP handler from the service implementation. It returns
132+// the path on which to mount the handler and the handler itself.
133+//
134+// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
135+// and JSON codecs. They also support gzip compression.
136+func NewTrustedKeyServiceHandler(svc TrustedKeyServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
137+ trustedKeyServiceMethods := ermite.File_ermite_signature_proto.Services().ByName("TrustedKeyService").Methods()
138+ trustedKeyServiceListTrustedKeysHandler := connect.NewUnaryHandler(
139+ TrustedKeyServiceListTrustedKeysProcedure,
140+ svc.ListTrustedKeys,
141+ connect.WithSchema(trustedKeyServiceMethods.ByName("ListTrustedKeys")),
142+ connect.WithHandlerOptions(opts...),
143+ )
144+ trustedKeyServiceAddTrustedKeyHandler := connect.NewUnaryHandler(
145+ TrustedKeyServiceAddTrustedKeyProcedure,
146+ svc.AddTrustedKey,
147+ connect.WithSchema(trustedKeyServiceMethods.ByName("AddTrustedKey")),
148+ connect.WithHandlerOptions(opts...),
149+ )
150+ trustedKeyServiceRemoveTrustedKeyHandler := connect.NewUnaryHandler(
151+ TrustedKeyServiceRemoveTrustedKeyProcedure,
152+ svc.RemoveTrustedKey,
153+ connect.WithSchema(trustedKeyServiceMethods.ByName("RemoveTrustedKey")),
154+ connect.WithHandlerOptions(opts...),
155+ )
156+ return "/ermite.TrustedKeyService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
157+ switch r.URL.Path {
158+ case TrustedKeyServiceListTrustedKeysProcedure:
159+ trustedKeyServiceListTrustedKeysHandler.ServeHTTP(w, r)
160+ case TrustedKeyServiceAddTrustedKeyProcedure:
161+ trustedKeyServiceAddTrustedKeyHandler.ServeHTTP(w, r)
162+ case TrustedKeyServiceRemoveTrustedKeyProcedure:
163+ trustedKeyServiceRemoveTrustedKeyHandler.ServeHTTP(w, r)
164+ default:
165+ http.NotFound(w, r)
166+ }
167+ })
168+}
169+
170+// UnimplementedTrustedKeyServiceHandler returns CodeUnimplemented from all methods.
171+type UnimplementedTrustedKeyServiceHandler struct{}
172+
173+func (UnimplementedTrustedKeyServiceHandler) ListTrustedKeys(context.Context, *connect.Request[ermite.ListTrustedKeysRequest]) (*connect.Response[ermite.ListTrustedKeysResponse], error) {
174+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.ListTrustedKeys is not implemented"))
175+}
176+
177+func (UnimplementedTrustedKeyServiceHandler) AddTrustedKey(context.Context, *connect.Request[ermite.AddTrustedKeyRequest]) (*connect.Response[ermite.AddTrustedKeyResponse], error) {
178+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.AddTrustedKey is not implemented"))
179+}
180+
181+func (UnimplementedTrustedKeyServiceHandler) RemoveTrustedKey(context.Context, *connect.Request[ermite.RemoveTrustedKeyRequest]) (*connect.Response[ermite.RemoveTrustedKeyResponse], error) {
182+ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.TrustedKeyService.RemoveTrustedKey is not implemented"))
183+}
A gen/ermite/signature.pb.go +759 -0
@@ -0,0 +1,759 @@
1+// SPDX-License-Identifier: MIT
2+
3+// Code generated by protoc-gen-go. DO NOT EDIT.
4+// versions:
5+// protoc-gen-go v1.36.12
6+// protoc (unknown)
7+// source: ermite/signature.proto
8+
9+package ermite
10+
11+import (
12+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
13+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
14+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
15+ reflect "reflect"
16+ sync "sync"
17+ unsafe "unsafe"
18+)
19+
20+const (
21+ // Verify that this generated code is sufficiently up-to-date.
22+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
23+ // Verify that runtime/protoimpl is sufficiently up-to-date.
24+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
25+)
26+
27+// SignatureFormat is the protocol of a commit signature.
28+type SignatureFormat int32
29+
30+const (
31+ // Not signed, or not set.
32+ SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED SignatureFormat = 0
33+ // Git SSH signature (gpg.format=ssh, "-----BEGIN SSH SIGNATURE-----").
34+ SignatureFormat_SIGNATURE_FORMAT_SSH SignatureFormat = 1
35+ // OpenPGP signature (gpg.format=openpgp, "-----BEGIN PGP SIGNATURE-----").
36+ SignatureFormat_SIGNATURE_FORMAT_GPG SignatureFormat = 2
37+ // X.509 (gpgsm) signature. Recognized, never verified.
38+ SignatureFormat_SIGNATURE_FORMAT_X509 SignatureFormat = 3
39+)
40+
41+// Enum value maps for SignatureFormat.
42+var (
43+ SignatureFormat_name = map[int32]string{
44+ 0: "SIGNATURE_FORMAT_UNSPECIFIED",
45+ 1: "SIGNATURE_FORMAT_SSH",
46+ 2: "SIGNATURE_FORMAT_GPG",
47+ 3: "SIGNATURE_FORMAT_X509",
48+ }
49+ SignatureFormat_value = map[string]int32{
50+ "SIGNATURE_FORMAT_UNSPECIFIED": 0,
51+ "SIGNATURE_FORMAT_SSH": 1,
52+ "SIGNATURE_FORMAT_GPG": 2,
53+ "SIGNATURE_FORMAT_X509": 3,
54+ }
55+)
56+
57+func (x SignatureFormat) Enum() *SignatureFormat {
58+ p := new(SignatureFormat)
59+ *p = x
60+ return p
61+}
62+
63+func (x SignatureFormat) String() string {
64+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
65+}
66+
67+func (SignatureFormat) Descriptor() protoreflect.EnumDescriptor {
68+ return file_ermite_signature_proto_enumTypes[0].Descriptor()
69+}
70+
71+func (SignatureFormat) Type() protoreflect.EnumType {
72+ return &file_ermite_signature_proto_enumTypes[0]
73+}
74+
75+func (x SignatureFormat) Number() protoreflect.EnumNumber {
76+ return protoreflect.EnumNumber(x)
77+}
78+
79+// Deprecated: Use SignatureFormat.Descriptor instead.
80+func (SignatureFormat) EnumDescriptor() ([]byte, []int) {
81+ return file_ermite_signature_proto_rawDescGZIP(), []int{0}
82+}
83+
84+// SignatureStatus is the outcome of checking the signature of a commit.
85+type SignatureStatus int32
86+
87+const (
88+ // The server did not check the commit (it could not be read).
89+ SignatureStatus_SIGNATURE_STATUS_UNSPECIFIED SignatureStatus = 0
90+ // The commit carries no signature.
91+ SignatureStatus_SIGNATURE_STATUS_UNSIGNED SignatureStatus = 1
92+ // Valid signature by a trusted key that is trusted for the committer email.
93+ SignatureStatus_SIGNATURE_STATUS_VERIFIED SignatureStatus = 2
94+ // Well-formed signature by a key the server does not trust.
95+ SignatureStatus_SIGNATURE_STATUS_UNKNOWN_KEY SignatureStatus = 3
96+ // The signature is malformed, does not match the commit, or uses a weak
97+ // hash (SHA-1 and older).
98+ SignatureStatus_SIGNATURE_STATUS_BAD_SIGNATURE SignatureStatus = 4
99+ // Valid signature by a trusted key that is not trusted for the committer
100+ // email.
101+ SignatureStatus_SIGNATURE_STATUS_EMAIL_MISMATCH SignatureStatus = 5
102+ // The OpenPGP key or signature had expired when the signature was made.
103+ SignatureStatus_SIGNATURE_STATUS_EXPIRED SignatureStatus = 6
104+ // The OpenPGP key is revoked.
105+ SignatureStatus_SIGNATURE_STATUS_REVOKED SignatureStatus = 7
106+ // The format is not verified by the server (X.509).
107+ SignatureStatus_SIGNATURE_STATUS_UNSUPPORTED SignatureStatus = 8
108+)
109+
110+// Enum value maps for SignatureStatus.
111+var (
112+ SignatureStatus_name = map[int32]string{
113+ 0: "SIGNATURE_STATUS_UNSPECIFIED",
114+ 1: "SIGNATURE_STATUS_UNSIGNED",
115+ 2: "SIGNATURE_STATUS_VERIFIED",
116+ 3: "SIGNATURE_STATUS_UNKNOWN_KEY",
117+ 4: "SIGNATURE_STATUS_BAD_SIGNATURE",
118+ 5: "SIGNATURE_STATUS_EMAIL_MISMATCH",
119+ 6: "SIGNATURE_STATUS_EXPIRED",
120+ 7: "SIGNATURE_STATUS_REVOKED",
121+ 8: "SIGNATURE_STATUS_UNSUPPORTED",
122+ }
123+ SignatureStatus_value = map[string]int32{
124+ "SIGNATURE_STATUS_UNSPECIFIED": 0,
125+ "SIGNATURE_STATUS_UNSIGNED": 1,
126+ "SIGNATURE_STATUS_VERIFIED": 2,
127+ "SIGNATURE_STATUS_UNKNOWN_KEY": 3,
128+ "SIGNATURE_STATUS_BAD_SIGNATURE": 4,
129+ "SIGNATURE_STATUS_EMAIL_MISMATCH": 5,
130+ "SIGNATURE_STATUS_EXPIRED": 6,
131+ "SIGNATURE_STATUS_REVOKED": 7,
132+ "SIGNATURE_STATUS_UNSUPPORTED": 8,
133+ }
134+)
135+
136+func (x SignatureStatus) Enum() *SignatureStatus {
137+ p := new(SignatureStatus)
138+ *p = x
139+ return p
140+}
141+
142+func (x SignatureStatus) String() string {
143+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
144+}
145+
146+func (SignatureStatus) Descriptor() protoreflect.EnumDescriptor {
147+ return file_ermite_signature_proto_enumTypes[1].Descriptor()
148+}
149+
150+func (SignatureStatus) Type() protoreflect.EnumType {
151+ return &file_ermite_signature_proto_enumTypes[1]
152+}
153+
154+func (x SignatureStatus) Number() protoreflect.EnumNumber {
155+ return protoreflect.EnumNumber(x)
156+}
157+
158+// Deprecated: Use SignatureStatus.Descriptor instead.
159+func (SignatureStatus) EnumDescriptor() ([]byte, []int) {
160+ return file_ermite_signature_proto_rawDescGZIP(), []int{1}
161+}
162+
163+// CommitVerification tells whether and how a commit is signed.
164+type CommitVerification struct {
165+ state protoimpl.MessageState `protogen:"open.v1"`
166+ Format SignatureFormat `protobuf:"varint,1,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
167+ Status SignatureStatus `protobuf:"varint,2,opt,name=status,proto3,enum=ermite.SignatureStatus" json:"status,omitempty"`
168+ // Fingerprint of the signing key when the signature names one:
169+ // "SHA256:<base64>" for SSH, upper-case hex for OpenPGP (the 16-digit
170+ // issuer key id when the key is unknown).
171+ Fingerprint string `protobuf:"bytes,3,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"`
172+ // KeyId is the id of the trusted key that matched; empty when none did.
173+ KeyId string `protobuf:"bytes,4,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
174+ // KeyTitle is the title of the trusted key that matched.
175+ KeyTitle string `protobuf:"bytes,5,opt,name=key_title,json=keyTitle,proto3" json:"key_title,omitempty"`
176+ unknownFields protoimpl.UnknownFields
177+ sizeCache protoimpl.SizeCache
178+}
179+
180+func (x *CommitVerification) Reset() {
181+ *x = CommitVerification{}
182+ mi := &file_ermite_signature_proto_msgTypes[0]
183+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
184+ ms.StoreMessageInfo(mi)
185+}
186+
187+func (x *CommitVerification) String() string {
188+ return protoimpl.X.MessageStringOf(x)
189+}
190+
191+func (*CommitVerification) ProtoMessage() {}
192+
193+func (x *CommitVerification) ProtoReflect() protoreflect.Message {
194+ mi := &file_ermite_signature_proto_msgTypes[0]
195+ if x != nil {
196+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
197+ if ms.LoadMessageInfo() == nil {
198+ ms.StoreMessageInfo(mi)
199+ }
200+ return ms
201+ }
202+ return mi.MessageOf(x)
203+}
204+
205+// Deprecated: Use CommitVerification.ProtoReflect.Descriptor instead.
206+func (*CommitVerification) Descriptor() ([]byte, []int) {
207+ return file_ermite_signature_proto_rawDescGZIP(), []int{0}
208+}
209+
210+func (x *CommitVerification) GetFormat() SignatureFormat {
211+ if x != nil {
212+ return x.Format
213+ }
214+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
215+}
216+
217+func (x *CommitVerification) GetStatus() SignatureStatus {
218+ if x != nil {
219+ return x.Status
220+ }
221+ return SignatureStatus_SIGNATURE_STATUS_UNSPECIFIED
222+}
223+
224+func (x *CommitVerification) GetFingerprint() string {
225+ if x != nil {
226+ return x.Fingerprint
227+ }
228+ return ""
229+}
230+
231+func (x *CommitVerification) GetKeyId() string {
232+ if x != nil {
233+ return x.KeyId
234+ }
235+ return ""
236+}
237+
238+func (x *CommitVerification) GetKeyTitle() string {
239+ if x != nil {
240+ return x.KeyTitle
241+ }
242+ return ""
243+}
244+
245+// TrustedKey is a public key whose signatures the server accepts for the
246+// listed committer emails.
247+type TrustedKey struct {
248+ state protoimpl.MessageState `protogen:"open.v1"`
249+ // Id is the key fingerprint: "SHA256:<base64>" for SSH, the primary key
250+ // fingerprint in upper-case hex for OpenPGP.
251+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
252+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
253+ Format SignatureFormat `protobuf:"varint,2,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
254+ Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
255+ // PublicKey is "<type> <base64>" for SSH, the armored public key for
256+ // OpenPGP.
257+ PublicKey string `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
258+ // Emails are the committer emails the key may sign for, lower-case.
259+ Emails []string `protobuf:"bytes,5,rep,name=emails,proto3" json:"emails,omitempty"`
260+ CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
261+ // Builtin is true for the server's own signing key
262+ // (ServerService.GetSigningKey): always trusted, cannot be removed.
263+ Builtin bool `protobuf:"varint,7,opt,name=builtin,proto3" json:"builtin,omitempty"`
264+ unknownFields protoimpl.UnknownFields
265+ sizeCache protoimpl.SizeCache
266+}
267+
268+func (x *TrustedKey) Reset() {
269+ *x = TrustedKey{}
270+ mi := &file_ermite_signature_proto_msgTypes[1]
271+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
272+ ms.StoreMessageInfo(mi)
273+}
274+
275+func (x *TrustedKey) String() string {
276+ return protoimpl.X.MessageStringOf(x)
277+}
278+
279+func (*TrustedKey) ProtoMessage() {}
280+
281+func (x *TrustedKey) ProtoReflect() protoreflect.Message {
282+ mi := &file_ermite_signature_proto_msgTypes[1]
283+ if x != nil {
284+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
285+ if ms.LoadMessageInfo() == nil {
286+ ms.StoreMessageInfo(mi)
287+ }
288+ return ms
289+ }
290+ return mi.MessageOf(x)
291+}
292+
293+// Deprecated: Use TrustedKey.ProtoReflect.Descriptor instead.
294+func (*TrustedKey) Descriptor() ([]byte, []int) {
295+ return file_ermite_signature_proto_rawDescGZIP(), []int{1}
296+}
297+
298+func (x *TrustedKey) GetId() string {
299+ if x != nil {
300+ return x.Id
301+ }
302+ return ""
303+}
304+
305+func (x *TrustedKey) GetFormat() SignatureFormat {
306+ if x != nil {
307+ return x.Format
308+ }
309+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
310+}
311+
312+func (x *TrustedKey) GetTitle() string {
313+ if x != nil {
314+ return x.Title
315+ }
316+ return ""
317+}
318+
319+func (x *TrustedKey) GetPublicKey() string {
320+ if x != nil {
321+ return x.PublicKey
322+ }
323+ return ""
324+}
325+
326+func (x *TrustedKey) GetEmails() []string {
327+ if x != nil {
328+ return x.Emails
329+ }
330+ return nil
331+}
332+
333+func (x *TrustedKey) GetCreatedAt() *timestamppb.Timestamp {
334+ if x != nil {
335+ return x.CreatedAt
336+ }
337+ return nil
338+}
339+
340+func (x *TrustedKey) GetBuiltin() bool {
341+ if x != nil {
342+ return x.Builtin
343+ }
344+ return false
345+}
346+
347+// ListTrustedKeysRequest is empty.
348+type ListTrustedKeysRequest struct {
349+ state protoimpl.MessageState `protogen:"open.v1"`
350+ unknownFields protoimpl.UnknownFields
351+ sizeCache protoimpl.SizeCache
352+}
353+
354+func (x *ListTrustedKeysRequest) Reset() {
355+ *x = ListTrustedKeysRequest{}
356+ mi := &file_ermite_signature_proto_msgTypes[2]
357+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
358+ ms.StoreMessageInfo(mi)
359+}
360+
361+func (x *ListTrustedKeysRequest) String() string {
362+ return protoimpl.X.MessageStringOf(x)
363+}
364+
365+func (*ListTrustedKeysRequest) ProtoMessage() {}
366+
367+func (x *ListTrustedKeysRequest) ProtoReflect() protoreflect.Message {
368+ mi := &file_ermite_signature_proto_msgTypes[2]
369+ if x != nil {
370+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
371+ if ms.LoadMessageInfo() == nil {
372+ ms.StoreMessageInfo(mi)
373+ }
374+ return ms
375+ }
376+ return mi.MessageOf(x)
377+}
378+
379+// Deprecated: Use ListTrustedKeysRequest.ProtoReflect.Descriptor instead.
380+func (*ListTrustedKeysRequest) Descriptor() ([]byte, []int) {
381+ return file_ermite_signature_proto_rawDescGZIP(), []int{2}
382+}
383+
384+// ListTrustedKeysResponse lists every trusted key.
385+type ListTrustedKeysResponse struct {
386+ state protoimpl.MessageState `protogen:"open.v1"`
387+ Keys []*TrustedKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"`
388+ unknownFields protoimpl.UnknownFields
389+ sizeCache protoimpl.SizeCache
390+}
391+
392+func (x *ListTrustedKeysResponse) Reset() {
393+ *x = ListTrustedKeysResponse{}
394+ mi := &file_ermite_signature_proto_msgTypes[3]
395+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
396+ ms.StoreMessageInfo(mi)
397+}
398+
399+func (x *ListTrustedKeysResponse) String() string {
400+ return protoimpl.X.MessageStringOf(x)
401+}
402+
403+func (*ListTrustedKeysResponse) ProtoMessage() {}
404+
405+func (x *ListTrustedKeysResponse) ProtoReflect() protoreflect.Message {
406+ mi := &file_ermite_signature_proto_msgTypes[3]
407+ if x != nil {
408+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
409+ if ms.LoadMessageInfo() == nil {
410+ ms.StoreMessageInfo(mi)
411+ }
412+ return ms
413+ }
414+ return mi.MessageOf(x)
415+}
416+
417+// Deprecated: Use ListTrustedKeysResponse.ProtoReflect.Descriptor instead.
418+func (*ListTrustedKeysResponse) Descriptor() ([]byte, []int) {
419+ return file_ermite_signature_proto_rawDescGZIP(), []int{3}
420+}
421+
422+func (x *ListTrustedKeysResponse) GetKeys() []*TrustedKey {
423+ if x != nil {
424+ return x.Keys
425+ }
426+ return nil
427+}
428+
429+// AddTrustedKeyRequest describes the key to trust.
430+type AddTrustedKeyRequest struct {
431+ state protoimpl.MessageState `protogen:"open.v1"`
432+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
433+ Format SignatureFormat `protobuf:"varint,1,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
434+ // Title is a label, 1 to 100 bytes.
435+ Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
436+ // PublicKey is an authorized_keys line for SSH, or an armored public key
437+ // block for OpenPGP (at most 64 KiB).
438+ PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
439+ // Emails are the committer emails the key may sign for, 1 to 10.
440+ Emails []string `protobuf:"bytes,4,rep,name=emails,proto3" json:"emails,omitempty"`
441+ unknownFields protoimpl.UnknownFields
442+ sizeCache protoimpl.SizeCache
443+}
444+
445+func (x *AddTrustedKeyRequest) Reset() {
446+ *x = AddTrustedKeyRequest{}
447+ mi := &file_ermite_signature_proto_msgTypes[4]
448+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
449+ ms.StoreMessageInfo(mi)
450+}
451+
452+func (x *AddTrustedKeyRequest) String() string {
453+ return protoimpl.X.MessageStringOf(x)
454+}
455+
456+func (*AddTrustedKeyRequest) ProtoMessage() {}
457+
458+func (x *AddTrustedKeyRequest) ProtoReflect() protoreflect.Message {
459+ mi := &file_ermite_signature_proto_msgTypes[4]
460+ if x != nil {
461+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
462+ if ms.LoadMessageInfo() == nil {
463+ ms.StoreMessageInfo(mi)
464+ }
465+ return ms
466+ }
467+ return mi.MessageOf(x)
468+}
469+
470+// Deprecated: Use AddTrustedKeyRequest.ProtoReflect.Descriptor instead.
471+func (*AddTrustedKeyRequest) Descriptor() ([]byte, []int) {
472+ return file_ermite_signature_proto_rawDescGZIP(), []int{4}
473+}
474+
475+func (x *AddTrustedKeyRequest) GetFormat() SignatureFormat {
476+ if x != nil {
477+ return x.Format
478+ }
479+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
480+}
481+
482+func (x *AddTrustedKeyRequest) GetTitle() string {
483+ if x != nil {
484+ return x.Title
485+ }
486+ return ""
487+}
488+
489+func (x *AddTrustedKeyRequest) GetPublicKey() string {
490+ if x != nil {
491+ return x.PublicKey
492+ }
493+ return ""
494+}
495+
496+func (x *AddTrustedKeyRequest) GetEmails() []string {
497+ if x != nil {
498+ return x.Emails
499+ }
500+ return nil
501+}
502+
503+// AddTrustedKeyResponse returns the stored key.
504+type AddTrustedKeyResponse struct {
505+ state protoimpl.MessageState `protogen:"open.v1"`
506+ Key *TrustedKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
507+ unknownFields protoimpl.UnknownFields
508+ sizeCache protoimpl.SizeCache
509+}
510+
511+func (x *AddTrustedKeyResponse) Reset() {
512+ *x = AddTrustedKeyResponse{}
513+ mi := &file_ermite_signature_proto_msgTypes[5]
514+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
515+ ms.StoreMessageInfo(mi)
516+}
517+
518+func (x *AddTrustedKeyResponse) String() string {
519+ return protoimpl.X.MessageStringOf(x)
520+}
521+
522+func (*AddTrustedKeyResponse) ProtoMessage() {}
523+
524+func (x *AddTrustedKeyResponse) ProtoReflect() protoreflect.Message {
525+ mi := &file_ermite_signature_proto_msgTypes[5]
526+ if x != nil {
527+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
528+ if ms.LoadMessageInfo() == nil {
529+ ms.StoreMessageInfo(mi)
530+ }
531+ return ms
532+ }
533+ return mi.MessageOf(x)
534+}
535+
536+// Deprecated: Use AddTrustedKeyResponse.ProtoReflect.Descriptor instead.
537+func (*AddTrustedKeyResponse) Descriptor() ([]byte, []int) {
538+ return file_ermite_signature_proto_rawDescGZIP(), []int{5}
539+}
540+
541+func (x *AddTrustedKeyResponse) GetKey() *TrustedKey {
542+ if x != nil {
543+ return x.Key
544+ }
545+ return nil
546+}
547+
548+// RemoveTrustedKeyRequest names the key to remove.
549+type RemoveTrustedKeyRequest struct {
550+ state protoimpl.MessageState `protogen:"open.v1"`
551+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
552+ unknownFields protoimpl.UnknownFields
553+ sizeCache protoimpl.SizeCache
554+}
555+
556+func (x *RemoveTrustedKeyRequest) Reset() {
557+ *x = RemoveTrustedKeyRequest{}
558+ mi := &file_ermite_signature_proto_msgTypes[6]
559+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
560+ ms.StoreMessageInfo(mi)
561+}
562+
563+func (x *RemoveTrustedKeyRequest) String() string {
564+ return protoimpl.X.MessageStringOf(x)
565+}
566+
567+func (*RemoveTrustedKeyRequest) ProtoMessage() {}
568+
569+func (x *RemoveTrustedKeyRequest) ProtoReflect() protoreflect.Message {
570+ mi := &file_ermite_signature_proto_msgTypes[6]
571+ if x != nil {
572+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
573+ if ms.LoadMessageInfo() == nil {
574+ ms.StoreMessageInfo(mi)
575+ }
576+ return ms
577+ }
578+ return mi.MessageOf(x)
579+}
580+
581+// Deprecated: Use RemoveTrustedKeyRequest.ProtoReflect.Descriptor instead.
582+func (*RemoveTrustedKeyRequest) Descriptor() ([]byte, []int) {
583+ return file_ermite_signature_proto_rawDescGZIP(), []int{6}
584+}
585+
586+func (x *RemoveTrustedKeyRequest) GetId() string {
587+ if x != nil {
588+ return x.Id
589+ }
590+ return ""
591+}
592+
593+// RemoveTrustedKeyResponse is empty.
594+type RemoveTrustedKeyResponse struct {
595+ state protoimpl.MessageState `protogen:"open.v1"`
596+ unknownFields protoimpl.UnknownFields
597+ sizeCache protoimpl.SizeCache
598+}
599+
600+func (x *RemoveTrustedKeyResponse) Reset() {
601+ *x = RemoveTrustedKeyResponse{}
602+ mi := &file_ermite_signature_proto_msgTypes[7]
603+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
604+ ms.StoreMessageInfo(mi)
605+}
606+
607+func (x *RemoveTrustedKeyResponse) String() string {
608+ return protoimpl.X.MessageStringOf(x)
609+}
610+
611+func (*RemoveTrustedKeyResponse) ProtoMessage() {}
612+
613+func (x *RemoveTrustedKeyResponse) ProtoReflect() protoreflect.Message {
614+ mi := &file_ermite_signature_proto_msgTypes[7]
615+ if x != nil {
616+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
617+ if ms.LoadMessageInfo() == nil {
618+ ms.StoreMessageInfo(mi)
619+ }
620+ return ms
621+ }
622+ return mi.MessageOf(x)
623+}
624+
625+// Deprecated: Use RemoveTrustedKeyResponse.ProtoReflect.Descriptor instead.
626+func (*RemoveTrustedKeyResponse) Descriptor() ([]byte, []int) {
627+ return file_ermite_signature_proto_rawDescGZIP(), []int{7}
628+}
629+
630+var File_ermite_signature_proto protoreflect.FileDescriptor
631+
632+const file_ermite_signature_proto_rawDesc = "" +
633+ "\n" +
634+ "\x16ermite/signature.proto\x12\x06ermite\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcc\x01\n" +
635+ "\x12CommitVerification\x12/\n" +
636+ "\x06format\x18\x01 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12/\n" +
637+ "\x06status\x18\x02 \x01(\x0e2\x17.ermite.SignatureStatusR\x06status\x12 \n" +
638+ "\vfingerprint\x18\x03 \x01(\tR\vfingerprint\x12\x15\n" +
639+ "\x06key_id\x18\x04 \x01(\tR\x05keyId\x12\x1b\n" +
640+ "\tkey_title\x18\x05 \x01(\tR\bkeyTitle\"\xef\x01\n" +
641+ "\n" +
642+ "TrustedKey\x12\x0e\n" +
643+ "\x02id\x18\x01 \x01(\tR\x02id\x12/\n" +
644+ "\x06format\x18\x02 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12\x14\n" +
645+ "\x05title\x18\x03 \x01(\tR\x05title\x12\x1d\n" +
646+ "\n" +
647+ "public_key\x18\x04 \x01(\tR\tpublicKey\x12\x16\n" +
648+ "\x06emails\x18\x05 \x03(\tR\x06emails\x129\n" +
649+ "\n" +
650+ "created_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x18\n" +
651+ "\abuiltin\x18\a \x01(\bR\abuiltin\"\x18\n" +
652+ "\x16ListTrustedKeysRequest\"A\n" +
653+ "\x17ListTrustedKeysResponse\x12&\n" +
654+ "\x04keys\x18\x01 \x03(\v2\x12.ermite.TrustedKeyR\x04keys\"\x94\x01\n" +
655+ "\x14AddTrustedKeyRequest\x12/\n" +
656+ "\x06format\x18\x01 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12\x14\n" +
657+ "\x05title\x18\x02 \x01(\tR\x05title\x12\x1d\n" +
658+ "\n" +
659+ "public_key\x18\x03 \x01(\tR\tpublicKey\x12\x16\n" +
660+ "\x06emails\x18\x04 \x03(\tR\x06emails\"=\n" +
661+ "\x15AddTrustedKeyResponse\x12$\n" +
662+ "\x03key\x18\x01 \x01(\v2\x12.ermite.TrustedKeyR\x03key\")\n" +
663+ "\x17RemoveTrustedKeyRequest\x12\x0e\n" +
664+ "\x02id\x18\x01 \x01(\tR\x02id\"\x1a\n" +
665+ "\x18RemoveTrustedKeyResponse*\x82\x01\n" +
666+ "\x0fSignatureFormat\x12 \n" +
667+ "\x1cSIGNATURE_FORMAT_UNSPECIFIED\x10\x00\x12\x18\n" +
668+ "\x14SIGNATURE_FORMAT_SSH\x10\x01\x12\x18\n" +
669+ "\x14SIGNATURE_FORMAT_GPG\x10\x02\x12\x19\n" +
670+ "\x15SIGNATURE_FORMAT_X509\x10\x03*\xba\x02\n" +
671+ "\x0fSignatureStatus\x12 \n" +
672+ "\x1cSIGNATURE_STATUS_UNSPECIFIED\x10\x00\x12\x1d\n" +
673+ "\x19SIGNATURE_STATUS_UNSIGNED\x10\x01\x12\x1d\n" +
674+ "\x19SIGNATURE_STATUS_VERIFIED\x10\x02\x12 \n" +
675+ "\x1cSIGNATURE_STATUS_UNKNOWN_KEY\x10\x03\x12\"\n" +
676+ "\x1eSIGNATURE_STATUS_BAD_SIGNATURE\x10\x04\x12#\n" +
677+ "\x1fSIGNATURE_STATUS_EMAIL_MISMATCH\x10\x05\x12\x1c\n" +
678+ "\x18SIGNATURE_STATUS_EXPIRED\x10\x06\x12\x1c\n" +
679+ "\x18SIGNATURE_STATUS_REVOKED\x10\a\x12 \n" +
680+ "\x1cSIGNATURE_STATUS_UNSUPPORTED\x10\b2\x8c\x02\n" +
681+ "\x11TrustedKeyService\x12R\n" +
682+ "\x0fListTrustedKeys\x12\x1e.ermite.ListTrustedKeysRequest\x1a\x1f.ermite.ListTrustedKeysResponse\x12L\n" +
683+ "\rAddTrustedKey\x12\x1c.ermite.AddTrustedKeyRequest\x1a\x1d.ermite.AddTrustedKeyResponse\x12U\n" +
684+ "\x10RemoveTrustedKey\x12\x1f.ermite.RemoveTrustedKeyRequest\x1a .ermite.RemoveTrustedKeyResponseBu\n" +
685+ "\n" +
686+ "com.ermiteB\x0eSignatureProtoP\x01Z\x1fbnema.dev/ermite-api/gen/ermite\xa2\x02\x03EXX\xaa\x02\x06Ermite\xca\x02\x06Ermite\xe2\x02\x12Ermite\\GPBMetadata\xea\x02\x06Ermiteb\x06proto3"
687+
688+var (
689+ file_ermite_signature_proto_rawDescOnce sync.Once
690+ file_ermite_signature_proto_rawDescData []byte
691+)
692+
693+func file_ermite_signature_proto_rawDescGZIP() []byte {
694+ file_ermite_signature_proto_rawDescOnce.Do(func() {
695+ file_ermite_signature_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ermite_signature_proto_rawDesc), len(file_ermite_signature_proto_rawDesc)))
696+ })
697+ return file_ermite_signature_proto_rawDescData
698+}
699+
700+var file_ermite_signature_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
701+var file_ermite_signature_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
702+var file_ermite_signature_proto_goTypes = []any{
703+ (SignatureFormat)(0), // 0: ermite.SignatureFormat
704+ (SignatureStatus)(0), // 1: ermite.SignatureStatus
705+ (*CommitVerification)(nil), // 2: ermite.CommitVerification
706+ (*TrustedKey)(nil), // 3: ermite.TrustedKey
707+ (*ListTrustedKeysRequest)(nil), // 4: ermite.ListTrustedKeysRequest
708+ (*ListTrustedKeysResponse)(nil), // 5: ermite.ListTrustedKeysResponse
709+ (*AddTrustedKeyRequest)(nil), // 6: ermite.AddTrustedKeyRequest
710+ (*AddTrustedKeyResponse)(nil), // 7: ermite.AddTrustedKeyResponse
711+ (*RemoveTrustedKeyRequest)(nil), // 8: ermite.RemoveTrustedKeyRequest
712+ (*RemoveTrustedKeyResponse)(nil), // 9: ermite.RemoveTrustedKeyResponse
713+ (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp
714+}
715+var file_ermite_signature_proto_depIdxs = []int32{
716+ 0, // 0: ermite.CommitVerification.format:type_name -> ermite.SignatureFormat
717+ 1, // 1: ermite.CommitVerification.status:type_name -> ermite.SignatureStatus
718+ 0, // 2: ermite.TrustedKey.format:type_name -> ermite.SignatureFormat
719+ 10, // 3: ermite.TrustedKey.created_at:type_name -> google.protobuf.Timestamp
720+ 3, // 4: ermite.ListTrustedKeysResponse.keys:type_name -> ermite.TrustedKey
721+ 0, // 5: ermite.AddTrustedKeyRequest.format:type_name -> ermite.SignatureFormat
722+ 3, // 6: ermite.AddTrustedKeyResponse.key:type_name -> ermite.TrustedKey
723+ 4, // 7: ermite.TrustedKeyService.ListTrustedKeys:input_type -> ermite.ListTrustedKeysRequest
724+ 6, // 8: ermite.TrustedKeyService.AddTrustedKey:input_type -> ermite.AddTrustedKeyRequest
725+ 8, // 9: ermite.TrustedKeyService.RemoveTrustedKey:input_type -> ermite.RemoveTrustedKeyRequest
726+ 5, // 10: ermite.TrustedKeyService.ListTrustedKeys:output_type -> ermite.ListTrustedKeysResponse
727+ 7, // 11: ermite.TrustedKeyService.AddTrustedKey:output_type -> ermite.AddTrustedKeyResponse
728+ 9, // 12: ermite.TrustedKeyService.RemoveTrustedKey:output_type -> ermite.RemoveTrustedKeyResponse
729+ 10, // [10:13] is the sub-list for method output_type
730+ 7, // [7:10] is the sub-list for method input_type
731+ 7, // [7:7] is the sub-list for extension type_name
732+ 7, // [7:7] is the sub-list for extension extendee
733+ 0, // [0:7] is the sub-list for field type_name
734+}
735+
736+func init() { file_ermite_signature_proto_init() }
737+func file_ermite_signature_proto_init() {
738+ if File_ermite_signature_proto != nil {
739+ return
740+ }
741+ type x struct{}
742+ out := protoimpl.TypeBuilder{
743+ File: protoimpl.DescBuilder{
744+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
745+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_ermite_signature_proto_rawDesc), len(file_ermite_signature_proto_rawDesc)),
746+ NumEnums: 2,
747+ NumMessages: 8,
748+ NumExtensions: 0,
749+ NumServices: 1,
750+ },
751+ GoTypes: file_ermite_signature_proto_goTypes,
752+ DependencyIndexes: file_ermite_signature_proto_depIdxs,
753+ EnumInfos: file_ermite_signature_proto_enumTypes,
754+ MessageInfos: file_ermite_signature_proto_msgTypes,
755+ }.Build()
756+ File_ermite_signature_proto = out.File
757+ file_ermite_signature_proto_goTypes = nil
758+ file_ermite_signature_proto_depIdxs = nil
759+}
@@ -0,0 +1,759 @@
1+// SPDX-License-Identifier: MIT
2+
3+// Code generated by protoc-gen-go. DO NOT EDIT.
4+// versions:
5+// protoc-gen-go v1.36.12
6+// protoc (unknown)
7+// source: ermite/signature.proto
8+
9+package ermite
10+
11+import (
12+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
13+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
14+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
15+ reflect "reflect"
16+ sync "sync"
17+ unsafe "unsafe"
18+)
19+
20+const (
21+ // Verify that this generated code is sufficiently up-to-date.
22+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
23+ // Verify that runtime/protoimpl is sufficiently up-to-date.
24+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
25+)
26+
27+// SignatureFormat is the protocol of a commit signature.
28+type SignatureFormat int32
29+
30+const (
31+ // Not signed, or not set.
32+ SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED SignatureFormat = 0
33+ // Git SSH signature (gpg.format=ssh, "-----BEGIN SSH SIGNATURE-----").
34+ SignatureFormat_SIGNATURE_FORMAT_SSH SignatureFormat = 1
35+ // OpenPGP signature (gpg.format=openpgp, "-----BEGIN PGP SIGNATURE-----").
36+ SignatureFormat_SIGNATURE_FORMAT_GPG SignatureFormat = 2
37+ // X.509 (gpgsm) signature. Recognized, never verified.
38+ SignatureFormat_SIGNATURE_FORMAT_X509 SignatureFormat = 3
39+)
40+
41+// Enum value maps for SignatureFormat.
42+var (
43+ SignatureFormat_name = map[int32]string{
44+ 0: "SIGNATURE_FORMAT_UNSPECIFIED",
45+ 1: "SIGNATURE_FORMAT_SSH",
46+ 2: "SIGNATURE_FORMAT_GPG",
47+ 3: "SIGNATURE_FORMAT_X509",
48+ }
49+ SignatureFormat_value = map[string]int32{
50+ "SIGNATURE_FORMAT_UNSPECIFIED": 0,
51+ "SIGNATURE_FORMAT_SSH": 1,
52+ "SIGNATURE_FORMAT_GPG": 2,
53+ "SIGNATURE_FORMAT_X509": 3,
54+ }
55+)
56+
57+func (x SignatureFormat) Enum() *SignatureFormat {
58+ p := new(SignatureFormat)
59+ *p = x
60+ return p
61+}
62+
63+func (x SignatureFormat) String() string {
64+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
65+}
66+
67+func (SignatureFormat) Descriptor() protoreflect.EnumDescriptor {
68+ return file_ermite_signature_proto_enumTypes[0].Descriptor()
69+}
70+
71+func (SignatureFormat) Type() protoreflect.EnumType {
72+ return &file_ermite_signature_proto_enumTypes[0]
73+}
74+
75+func (x SignatureFormat) Number() protoreflect.EnumNumber {
76+ return protoreflect.EnumNumber(x)
77+}
78+
79+// Deprecated: Use SignatureFormat.Descriptor instead.
80+func (SignatureFormat) EnumDescriptor() ([]byte, []int) {
81+ return file_ermite_signature_proto_rawDescGZIP(), []int{0}
82+}
83+
84+// SignatureStatus is the outcome of checking the signature of a commit.
85+type SignatureStatus int32
86+
87+const (
88+ // The server did not check the commit (it could not be read).
89+ SignatureStatus_SIGNATURE_STATUS_UNSPECIFIED SignatureStatus = 0
90+ // The commit carries no signature.
91+ SignatureStatus_SIGNATURE_STATUS_UNSIGNED SignatureStatus = 1
92+ // Valid signature by a trusted key that is trusted for the committer email.
93+ SignatureStatus_SIGNATURE_STATUS_VERIFIED SignatureStatus = 2
94+ // Well-formed signature by a key the server does not trust.
95+ SignatureStatus_SIGNATURE_STATUS_UNKNOWN_KEY SignatureStatus = 3
96+ // The signature is malformed, does not match the commit, or uses a weak
97+ // hash (SHA-1 and older).
98+ SignatureStatus_SIGNATURE_STATUS_BAD_SIGNATURE SignatureStatus = 4
99+ // Valid signature by a trusted key that is not trusted for the committer
100+ // email.
101+ SignatureStatus_SIGNATURE_STATUS_EMAIL_MISMATCH SignatureStatus = 5
102+ // The OpenPGP key or signature had expired when the signature was made.
103+ SignatureStatus_SIGNATURE_STATUS_EXPIRED SignatureStatus = 6
104+ // The OpenPGP key is revoked.
105+ SignatureStatus_SIGNATURE_STATUS_REVOKED SignatureStatus = 7
106+ // The format is not verified by the server (X.509).
107+ SignatureStatus_SIGNATURE_STATUS_UNSUPPORTED SignatureStatus = 8
108+)
109+
110+// Enum value maps for SignatureStatus.
111+var (
112+ SignatureStatus_name = map[int32]string{
113+ 0: "SIGNATURE_STATUS_UNSPECIFIED",
114+ 1: "SIGNATURE_STATUS_UNSIGNED",
115+ 2: "SIGNATURE_STATUS_VERIFIED",
116+ 3: "SIGNATURE_STATUS_UNKNOWN_KEY",
117+ 4: "SIGNATURE_STATUS_BAD_SIGNATURE",
118+ 5: "SIGNATURE_STATUS_EMAIL_MISMATCH",
119+ 6: "SIGNATURE_STATUS_EXPIRED",
120+ 7: "SIGNATURE_STATUS_REVOKED",
121+ 8: "SIGNATURE_STATUS_UNSUPPORTED",
122+ }
123+ SignatureStatus_value = map[string]int32{
124+ "SIGNATURE_STATUS_UNSPECIFIED": 0,
125+ "SIGNATURE_STATUS_UNSIGNED": 1,
126+ "SIGNATURE_STATUS_VERIFIED": 2,
127+ "SIGNATURE_STATUS_UNKNOWN_KEY": 3,
128+ "SIGNATURE_STATUS_BAD_SIGNATURE": 4,
129+ "SIGNATURE_STATUS_EMAIL_MISMATCH": 5,
130+ "SIGNATURE_STATUS_EXPIRED": 6,
131+ "SIGNATURE_STATUS_REVOKED": 7,
132+ "SIGNATURE_STATUS_UNSUPPORTED": 8,
133+ }
134+)
135+
136+func (x SignatureStatus) Enum() *SignatureStatus {
137+ p := new(SignatureStatus)
138+ *p = x
139+ return p
140+}
141+
142+func (x SignatureStatus) String() string {
143+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
144+}
145+
146+func (SignatureStatus) Descriptor() protoreflect.EnumDescriptor {
147+ return file_ermite_signature_proto_enumTypes[1].Descriptor()
148+}
149+
150+func (SignatureStatus) Type() protoreflect.EnumType {
151+ return &file_ermite_signature_proto_enumTypes[1]
152+}
153+
154+func (x SignatureStatus) Number() protoreflect.EnumNumber {
155+ return protoreflect.EnumNumber(x)
156+}
157+
158+// Deprecated: Use SignatureStatus.Descriptor instead.
159+func (SignatureStatus) EnumDescriptor() ([]byte, []int) {
160+ return file_ermite_signature_proto_rawDescGZIP(), []int{1}
161+}
162+
163+// CommitVerification tells whether and how a commit is signed.
164+type CommitVerification struct {
165+ state protoimpl.MessageState `protogen:"open.v1"`
166+ Format SignatureFormat `protobuf:"varint,1,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
167+ Status SignatureStatus `protobuf:"varint,2,opt,name=status,proto3,enum=ermite.SignatureStatus" json:"status,omitempty"`
168+ // Fingerprint of the signing key when the signature names one:
169+ // "SHA256:<base64>" for SSH, upper-case hex for OpenPGP (the 16-digit
170+ // issuer key id when the key is unknown).
171+ Fingerprint string `protobuf:"bytes,3,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"`
172+ // KeyId is the id of the trusted key that matched; empty when none did.
173+ KeyId string `protobuf:"bytes,4,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"`
174+ // KeyTitle is the title of the trusted key that matched.
175+ KeyTitle string `protobuf:"bytes,5,opt,name=key_title,json=keyTitle,proto3" json:"key_title,omitempty"`
176+ unknownFields protoimpl.UnknownFields
177+ sizeCache protoimpl.SizeCache
178+}
179+
180+func (x *CommitVerification) Reset() {
181+ *x = CommitVerification{}
182+ mi := &file_ermite_signature_proto_msgTypes[0]
183+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
184+ ms.StoreMessageInfo(mi)
185+}
186+
187+func (x *CommitVerification) String() string {
188+ return protoimpl.X.MessageStringOf(x)
189+}
190+
191+func (*CommitVerification) ProtoMessage() {}
192+
193+func (x *CommitVerification) ProtoReflect() protoreflect.Message {
194+ mi := &file_ermite_signature_proto_msgTypes[0]
195+ if x != nil {
196+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
197+ if ms.LoadMessageInfo() == nil {
198+ ms.StoreMessageInfo(mi)
199+ }
200+ return ms
201+ }
202+ return mi.MessageOf(x)
203+}
204+
205+// Deprecated: Use CommitVerification.ProtoReflect.Descriptor instead.
206+func (*CommitVerification) Descriptor() ([]byte, []int) {
207+ return file_ermite_signature_proto_rawDescGZIP(), []int{0}
208+}
209+
210+func (x *CommitVerification) GetFormat() SignatureFormat {
211+ if x != nil {
212+ return x.Format
213+ }
214+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
215+}
216+
217+func (x *CommitVerification) GetStatus() SignatureStatus {
218+ if x != nil {
219+ return x.Status
220+ }
221+ return SignatureStatus_SIGNATURE_STATUS_UNSPECIFIED
222+}
223+
224+func (x *CommitVerification) GetFingerprint() string {
225+ if x != nil {
226+ return x.Fingerprint
227+ }
228+ return ""
229+}
230+
231+func (x *CommitVerification) GetKeyId() string {
232+ if x != nil {
233+ return x.KeyId
234+ }
235+ return ""
236+}
237+
238+func (x *CommitVerification) GetKeyTitle() string {
239+ if x != nil {
240+ return x.KeyTitle
241+ }
242+ return ""
243+}
244+
245+// TrustedKey is a public key whose signatures the server accepts for the
246+// listed committer emails.
247+type TrustedKey struct {
248+ state protoimpl.MessageState `protogen:"open.v1"`
249+ // Id is the key fingerprint: "SHA256:<base64>" for SSH, the primary key
250+ // fingerprint in upper-case hex for OpenPGP.
251+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
252+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
253+ Format SignatureFormat `protobuf:"varint,2,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
254+ Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
255+ // PublicKey is "<type> <base64>" for SSH, the armored public key for
256+ // OpenPGP.
257+ PublicKey string `protobuf:"bytes,4,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
258+ // Emails are the committer emails the key may sign for, lower-case.
259+ Emails []string `protobuf:"bytes,5,rep,name=emails,proto3" json:"emails,omitempty"`
260+ CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
261+ // Builtin is true for the server's own signing key
262+ // (ServerService.GetSigningKey): always trusted, cannot be removed.
263+ Builtin bool `protobuf:"varint,7,opt,name=builtin,proto3" json:"builtin,omitempty"`
264+ unknownFields protoimpl.UnknownFields
265+ sizeCache protoimpl.SizeCache
266+}
267+
268+func (x *TrustedKey) Reset() {
269+ *x = TrustedKey{}
270+ mi := &file_ermite_signature_proto_msgTypes[1]
271+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
272+ ms.StoreMessageInfo(mi)
273+}
274+
275+func (x *TrustedKey) String() string {
276+ return protoimpl.X.MessageStringOf(x)
277+}
278+
279+func (*TrustedKey) ProtoMessage() {}
280+
281+func (x *TrustedKey) ProtoReflect() protoreflect.Message {
282+ mi := &file_ermite_signature_proto_msgTypes[1]
283+ if x != nil {
284+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
285+ if ms.LoadMessageInfo() == nil {
286+ ms.StoreMessageInfo(mi)
287+ }
288+ return ms
289+ }
290+ return mi.MessageOf(x)
291+}
292+
293+// Deprecated: Use TrustedKey.ProtoReflect.Descriptor instead.
294+func (*TrustedKey) Descriptor() ([]byte, []int) {
295+ return file_ermite_signature_proto_rawDescGZIP(), []int{1}
296+}
297+
298+func (x *TrustedKey) GetId() string {
299+ if x != nil {
300+ return x.Id
301+ }
302+ return ""
303+}
304+
305+func (x *TrustedKey) GetFormat() SignatureFormat {
306+ if x != nil {
307+ return x.Format
308+ }
309+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
310+}
311+
312+func (x *TrustedKey) GetTitle() string {
313+ if x != nil {
314+ return x.Title
315+ }
316+ return ""
317+}
318+
319+func (x *TrustedKey) GetPublicKey() string {
320+ if x != nil {
321+ return x.PublicKey
322+ }
323+ return ""
324+}
325+
326+func (x *TrustedKey) GetEmails() []string {
327+ if x != nil {
328+ return x.Emails
329+ }
330+ return nil
331+}
332+
333+func (x *TrustedKey) GetCreatedAt() *timestamppb.Timestamp {
334+ if x != nil {
335+ return x.CreatedAt
336+ }
337+ return nil
338+}
339+
340+func (x *TrustedKey) GetBuiltin() bool {
341+ if x != nil {
342+ return x.Builtin
343+ }
344+ return false
345+}
346+
347+// ListTrustedKeysRequest is empty.
348+type ListTrustedKeysRequest struct {
349+ state protoimpl.MessageState `protogen:"open.v1"`
350+ unknownFields protoimpl.UnknownFields
351+ sizeCache protoimpl.SizeCache
352+}
353+
354+func (x *ListTrustedKeysRequest) Reset() {
355+ *x = ListTrustedKeysRequest{}
356+ mi := &file_ermite_signature_proto_msgTypes[2]
357+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
358+ ms.StoreMessageInfo(mi)
359+}
360+
361+func (x *ListTrustedKeysRequest) String() string {
362+ return protoimpl.X.MessageStringOf(x)
363+}
364+
365+func (*ListTrustedKeysRequest) ProtoMessage() {}
366+
367+func (x *ListTrustedKeysRequest) ProtoReflect() protoreflect.Message {
368+ mi := &file_ermite_signature_proto_msgTypes[2]
369+ if x != nil {
370+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
371+ if ms.LoadMessageInfo() == nil {
372+ ms.StoreMessageInfo(mi)
373+ }
374+ return ms
375+ }
376+ return mi.MessageOf(x)
377+}
378+
379+// Deprecated: Use ListTrustedKeysRequest.ProtoReflect.Descriptor instead.
380+func (*ListTrustedKeysRequest) Descriptor() ([]byte, []int) {
381+ return file_ermite_signature_proto_rawDescGZIP(), []int{2}
382+}
383+
384+// ListTrustedKeysResponse lists every trusted key.
385+type ListTrustedKeysResponse struct {
386+ state protoimpl.MessageState `protogen:"open.v1"`
387+ Keys []*TrustedKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"`
388+ unknownFields protoimpl.UnknownFields
389+ sizeCache protoimpl.SizeCache
390+}
391+
392+func (x *ListTrustedKeysResponse) Reset() {
393+ *x = ListTrustedKeysResponse{}
394+ mi := &file_ermite_signature_proto_msgTypes[3]
395+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
396+ ms.StoreMessageInfo(mi)
397+}
398+
399+func (x *ListTrustedKeysResponse) String() string {
400+ return protoimpl.X.MessageStringOf(x)
401+}
402+
403+func (*ListTrustedKeysResponse) ProtoMessage() {}
404+
405+func (x *ListTrustedKeysResponse) ProtoReflect() protoreflect.Message {
406+ mi := &file_ermite_signature_proto_msgTypes[3]
407+ if x != nil {
408+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
409+ if ms.LoadMessageInfo() == nil {
410+ ms.StoreMessageInfo(mi)
411+ }
412+ return ms
413+ }
414+ return mi.MessageOf(x)
415+}
416+
417+// Deprecated: Use ListTrustedKeysResponse.ProtoReflect.Descriptor instead.
418+func (*ListTrustedKeysResponse) Descriptor() ([]byte, []int) {
419+ return file_ermite_signature_proto_rawDescGZIP(), []int{3}
420+}
421+
422+func (x *ListTrustedKeysResponse) GetKeys() []*TrustedKey {
423+ if x != nil {
424+ return x.Keys
425+ }
426+ return nil
427+}
428+
429+// AddTrustedKeyRequest describes the key to trust.
430+type AddTrustedKeyRequest struct {
431+ state protoimpl.MessageState `protogen:"open.v1"`
432+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
433+ Format SignatureFormat `protobuf:"varint,1,opt,name=format,proto3,enum=ermite.SignatureFormat" json:"format,omitempty"`
434+ // Title is a label, 1 to 100 bytes.
435+ Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
436+ // PublicKey is an authorized_keys line for SSH, or an armored public key
437+ // block for OpenPGP (at most 64 KiB).
438+ PublicKey string `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
439+ // Emails are the committer emails the key may sign for, 1 to 10.
440+ Emails []string `protobuf:"bytes,4,rep,name=emails,proto3" json:"emails,omitempty"`
441+ unknownFields protoimpl.UnknownFields
442+ sizeCache protoimpl.SizeCache
443+}
444+
445+func (x *AddTrustedKeyRequest) Reset() {
446+ *x = AddTrustedKeyRequest{}
447+ mi := &file_ermite_signature_proto_msgTypes[4]
448+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
449+ ms.StoreMessageInfo(mi)
450+}
451+
452+func (x *AddTrustedKeyRequest) String() string {
453+ return protoimpl.X.MessageStringOf(x)
454+}
455+
456+func (*AddTrustedKeyRequest) ProtoMessage() {}
457+
458+func (x *AddTrustedKeyRequest) ProtoReflect() protoreflect.Message {
459+ mi := &file_ermite_signature_proto_msgTypes[4]
460+ if x != nil {
461+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
462+ if ms.LoadMessageInfo() == nil {
463+ ms.StoreMessageInfo(mi)
464+ }
465+ return ms
466+ }
467+ return mi.MessageOf(x)
468+}
469+
470+// Deprecated: Use AddTrustedKeyRequest.ProtoReflect.Descriptor instead.
471+func (*AddTrustedKeyRequest) Descriptor() ([]byte, []int) {
472+ return file_ermite_signature_proto_rawDescGZIP(), []int{4}
473+}
474+
475+func (x *AddTrustedKeyRequest) GetFormat() SignatureFormat {
476+ if x != nil {
477+ return x.Format
478+ }
479+ return SignatureFormat_SIGNATURE_FORMAT_UNSPECIFIED
480+}
481+
482+func (x *AddTrustedKeyRequest) GetTitle() string {
483+ if x != nil {
484+ return x.Title
485+ }
486+ return ""
487+}
488+
489+func (x *AddTrustedKeyRequest) GetPublicKey() string {
490+ if x != nil {
491+ return x.PublicKey
492+ }
493+ return ""
494+}
495+
496+func (x *AddTrustedKeyRequest) GetEmails() []string {
497+ if x != nil {
498+ return x.Emails
499+ }
500+ return nil
501+}
502+
503+// AddTrustedKeyResponse returns the stored key.
504+type AddTrustedKeyResponse struct {
505+ state protoimpl.MessageState `protogen:"open.v1"`
506+ Key *TrustedKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
507+ unknownFields protoimpl.UnknownFields
508+ sizeCache protoimpl.SizeCache
509+}
510+
511+func (x *AddTrustedKeyResponse) Reset() {
512+ *x = AddTrustedKeyResponse{}
513+ mi := &file_ermite_signature_proto_msgTypes[5]
514+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
515+ ms.StoreMessageInfo(mi)
516+}
517+
518+func (x *AddTrustedKeyResponse) String() string {
519+ return protoimpl.X.MessageStringOf(x)
520+}
521+
522+func (*AddTrustedKeyResponse) ProtoMessage() {}
523+
524+func (x *AddTrustedKeyResponse) ProtoReflect() protoreflect.Message {
525+ mi := &file_ermite_signature_proto_msgTypes[5]
526+ if x != nil {
527+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
528+ if ms.LoadMessageInfo() == nil {
529+ ms.StoreMessageInfo(mi)
530+ }
531+ return ms
532+ }
533+ return mi.MessageOf(x)
534+}
535+
536+// Deprecated: Use AddTrustedKeyResponse.ProtoReflect.Descriptor instead.
537+func (*AddTrustedKeyResponse) Descriptor() ([]byte, []int) {
538+ return file_ermite_signature_proto_rawDescGZIP(), []int{5}
539+}
540+
541+func (x *AddTrustedKeyResponse) GetKey() *TrustedKey {
542+ if x != nil {
543+ return x.Key
544+ }
545+ return nil
546+}
547+
548+// RemoveTrustedKeyRequest names the key to remove.
549+type RemoveTrustedKeyRequest struct {
550+ state protoimpl.MessageState `protogen:"open.v1"`
551+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
552+ unknownFields protoimpl.UnknownFields
553+ sizeCache protoimpl.SizeCache
554+}
555+
556+func (x *RemoveTrustedKeyRequest) Reset() {
557+ *x = RemoveTrustedKeyRequest{}
558+ mi := &file_ermite_signature_proto_msgTypes[6]
559+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
560+ ms.StoreMessageInfo(mi)
561+}
562+
563+func (x *RemoveTrustedKeyRequest) String() string {
564+ return protoimpl.X.MessageStringOf(x)
565+}
566+
567+func (*RemoveTrustedKeyRequest) ProtoMessage() {}
568+
569+func (x *RemoveTrustedKeyRequest) ProtoReflect() protoreflect.Message {
570+ mi := &file_ermite_signature_proto_msgTypes[6]
571+ if x != nil {
572+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
573+ if ms.LoadMessageInfo() == nil {
574+ ms.StoreMessageInfo(mi)
575+ }
576+ return ms
577+ }
578+ return mi.MessageOf(x)
579+}
580+
581+// Deprecated: Use RemoveTrustedKeyRequest.ProtoReflect.Descriptor instead.
582+func (*RemoveTrustedKeyRequest) Descriptor() ([]byte, []int) {
583+ return file_ermite_signature_proto_rawDescGZIP(), []int{6}
584+}
585+
586+func (x *RemoveTrustedKeyRequest) GetId() string {
587+ if x != nil {
588+ return x.Id
589+ }
590+ return ""
591+}
592+
593+// RemoveTrustedKeyResponse is empty.
594+type RemoveTrustedKeyResponse struct {
595+ state protoimpl.MessageState `protogen:"open.v1"`
596+ unknownFields protoimpl.UnknownFields
597+ sizeCache protoimpl.SizeCache
598+}
599+
600+func (x *RemoveTrustedKeyResponse) Reset() {
601+ *x = RemoveTrustedKeyResponse{}
602+ mi := &file_ermite_signature_proto_msgTypes[7]
603+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
604+ ms.StoreMessageInfo(mi)
605+}
606+
607+func (x *RemoveTrustedKeyResponse) String() string {
608+ return protoimpl.X.MessageStringOf(x)
609+}
610+
611+func (*RemoveTrustedKeyResponse) ProtoMessage() {}
612+
613+func (x *RemoveTrustedKeyResponse) ProtoReflect() protoreflect.Message {
614+ mi := &file_ermite_signature_proto_msgTypes[7]
615+ if x != nil {
616+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
617+ if ms.LoadMessageInfo() == nil {
618+ ms.StoreMessageInfo(mi)
619+ }
620+ return ms
621+ }
622+ return mi.MessageOf(x)
623+}
624+
625+// Deprecated: Use RemoveTrustedKeyResponse.ProtoReflect.Descriptor instead.
626+func (*RemoveTrustedKeyResponse) Descriptor() ([]byte, []int) {
627+ return file_ermite_signature_proto_rawDescGZIP(), []int{7}
628+}
629+
630+var File_ermite_signature_proto protoreflect.FileDescriptor
631+
632+const file_ermite_signature_proto_rawDesc = "" +
633+ "\n" +
634+ "\x16ermite/signature.proto\x12\x06ermite\x1a\x1fgoogle/protobuf/timestamp.proto\"\xcc\x01\n" +
635+ "\x12CommitVerification\x12/\n" +
636+ "\x06format\x18\x01 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12/\n" +
637+ "\x06status\x18\x02 \x01(\x0e2\x17.ermite.SignatureStatusR\x06status\x12 \n" +
638+ "\vfingerprint\x18\x03 \x01(\tR\vfingerprint\x12\x15\n" +
639+ "\x06key_id\x18\x04 \x01(\tR\x05keyId\x12\x1b\n" +
640+ "\tkey_title\x18\x05 \x01(\tR\bkeyTitle\"\xef\x01\n" +
641+ "\n" +
642+ "TrustedKey\x12\x0e\n" +
643+ "\x02id\x18\x01 \x01(\tR\x02id\x12/\n" +
644+ "\x06format\x18\x02 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12\x14\n" +
645+ "\x05title\x18\x03 \x01(\tR\x05title\x12\x1d\n" +
646+ "\n" +
647+ "public_key\x18\x04 \x01(\tR\tpublicKey\x12\x16\n" +
648+ "\x06emails\x18\x05 \x03(\tR\x06emails\x129\n" +
649+ "\n" +
650+ "created_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x18\n" +
651+ "\abuiltin\x18\a \x01(\bR\abuiltin\"\x18\n" +
652+ "\x16ListTrustedKeysRequest\"A\n" +
653+ "\x17ListTrustedKeysResponse\x12&\n" +
654+ "\x04keys\x18\x01 \x03(\v2\x12.ermite.TrustedKeyR\x04keys\"\x94\x01\n" +
655+ "\x14AddTrustedKeyRequest\x12/\n" +
656+ "\x06format\x18\x01 \x01(\x0e2\x17.ermite.SignatureFormatR\x06format\x12\x14\n" +
657+ "\x05title\x18\x02 \x01(\tR\x05title\x12\x1d\n" +
658+ "\n" +
659+ "public_key\x18\x03 \x01(\tR\tpublicKey\x12\x16\n" +
660+ "\x06emails\x18\x04 \x03(\tR\x06emails\"=\n" +
661+ "\x15AddTrustedKeyResponse\x12$\n" +
662+ "\x03key\x18\x01 \x01(\v2\x12.ermite.TrustedKeyR\x03key\")\n" +
663+ "\x17RemoveTrustedKeyRequest\x12\x0e\n" +
664+ "\x02id\x18\x01 \x01(\tR\x02id\"\x1a\n" +
665+ "\x18RemoveTrustedKeyResponse*\x82\x01\n" +
666+ "\x0fSignatureFormat\x12 \n" +
667+ "\x1cSIGNATURE_FORMAT_UNSPECIFIED\x10\x00\x12\x18\n" +
668+ "\x14SIGNATURE_FORMAT_SSH\x10\x01\x12\x18\n" +
669+ "\x14SIGNATURE_FORMAT_GPG\x10\x02\x12\x19\n" +
670+ "\x15SIGNATURE_FORMAT_X509\x10\x03*\xba\x02\n" +
671+ "\x0fSignatureStatus\x12 \n" +
672+ "\x1cSIGNATURE_STATUS_UNSPECIFIED\x10\x00\x12\x1d\n" +
673+ "\x19SIGNATURE_STATUS_UNSIGNED\x10\x01\x12\x1d\n" +
674+ "\x19SIGNATURE_STATUS_VERIFIED\x10\x02\x12 \n" +
675+ "\x1cSIGNATURE_STATUS_UNKNOWN_KEY\x10\x03\x12\"\n" +
676+ "\x1eSIGNATURE_STATUS_BAD_SIGNATURE\x10\x04\x12#\n" +
677+ "\x1fSIGNATURE_STATUS_EMAIL_MISMATCH\x10\x05\x12\x1c\n" +
678+ "\x18SIGNATURE_STATUS_EXPIRED\x10\x06\x12\x1c\n" +
679+ "\x18SIGNATURE_STATUS_REVOKED\x10\a\x12 \n" +
680+ "\x1cSIGNATURE_STATUS_UNSUPPORTED\x10\b2\x8c\x02\n" +
681+ "\x11TrustedKeyService\x12R\n" +
682+ "\x0fListTrustedKeys\x12\x1e.ermite.ListTrustedKeysRequest\x1a\x1f.ermite.ListTrustedKeysResponse\x12L\n" +
683+ "\rAddTrustedKey\x12\x1c.ermite.AddTrustedKeyRequest\x1a\x1d.ermite.AddTrustedKeyResponse\x12U\n" +
684+ "\x10RemoveTrustedKey\x12\x1f.ermite.RemoveTrustedKeyRequest\x1a .ermite.RemoveTrustedKeyResponseBu\n" +
685+ "\n" +
686+ "com.ermiteB\x0eSignatureProtoP\x01Z\x1fbnema.dev/ermite-api/gen/ermite\xa2\x02\x03EXX\xaa\x02\x06Ermite\xca\x02\x06Ermite\xe2\x02\x12Ermite\\GPBMetadata\xea\x02\x06Ermiteb\x06proto3"
687+
688+var (
689+ file_ermite_signature_proto_rawDescOnce sync.Once
690+ file_ermite_signature_proto_rawDescData []byte
691+)
692+
693+func file_ermite_signature_proto_rawDescGZIP() []byte {
694+ file_ermite_signature_proto_rawDescOnce.Do(func() {
695+ file_ermite_signature_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ermite_signature_proto_rawDesc), len(file_ermite_signature_proto_rawDesc)))
696+ })
697+ return file_ermite_signature_proto_rawDescData
698+}
699+
700+var file_ermite_signature_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
701+var file_ermite_signature_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
702+var file_ermite_signature_proto_goTypes = []any{
703+ (SignatureFormat)(0), // 0: ermite.SignatureFormat
704+ (SignatureStatus)(0), // 1: ermite.SignatureStatus
705+ (*CommitVerification)(nil), // 2: ermite.CommitVerification
706+ (*TrustedKey)(nil), // 3: ermite.TrustedKey
707+ (*ListTrustedKeysRequest)(nil), // 4: ermite.ListTrustedKeysRequest
708+ (*ListTrustedKeysResponse)(nil), // 5: ermite.ListTrustedKeysResponse
709+ (*AddTrustedKeyRequest)(nil), // 6: ermite.AddTrustedKeyRequest
710+ (*AddTrustedKeyResponse)(nil), // 7: ermite.AddTrustedKeyResponse
711+ (*RemoveTrustedKeyRequest)(nil), // 8: ermite.RemoveTrustedKeyRequest
712+ (*RemoveTrustedKeyResponse)(nil), // 9: ermite.RemoveTrustedKeyResponse
713+ (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp
714+}
715+var file_ermite_signature_proto_depIdxs = []int32{
716+ 0, // 0: ermite.CommitVerification.format:type_name -> ermite.SignatureFormat
717+ 1, // 1: ermite.CommitVerification.status:type_name -> ermite.SignatureStatus
718+ 0, // 2: ermite.TrustedKey.format:type_name -> ermite.SignatureFormat
719+ 10, // 3: ermite.TrustedKey.created_at:type_name -> google.protobuf.Timestamp
720+ 3, // 4: ermite.ListTrustedKeysResponse.keys:type_name -> ermite.TrustedKey
721+ 0, // 5: ermite.AddTrustedKeyRequest.format:type_name -> ermite.SignatureFormat
722+ 3, // 6: ermite.AddTrustedKeyResponse.key:type_name -> ermite.TrustedKey
723+ 4, // 7: ermite.TrustedKeyService.ListTrustedKeys:input_type -> ermite.ListTrustedKeysRequest
724+ 6, // 8: ermite.TrustedKeyService.AddTrustedKey:input_type -> ermite.AddTrustedKeyRequest
725+ 8, // 9: ermite.TrustedKeyService.RemoveTrustedKey:input_type -> ermite.RemoveTrustedKeyRequest
726+ 5, // 10: ermite.TrustedKeyService.ListTrustedKeys:output_type -> ermite.ListTrustedKeysResponse
727+ 7, // 11: ermite.TrustedKeyService.AddTrustedKey:output_type -> ermite.AddTrustedKeyResponse
728+ 9, // 12: ermite.TrustedKeyService.RemoveTrustedKey:output_type -> ermite.RemoveTrustedKeyResponse
729+ 10, // [10:13] is the sub-list for method output_type
730+ 7, // [7:10] is the sub-list for method input_type
731+ 7, // [7:7] is the sub-list for extension type_name
732+ 7, // [7:7] is the sub-list for extension extendee
733+ 0, // [0:7] is the sub-list for field type_name
734+}
735+
736+func init() { file_ermite_signature_proto_init() }
737+func file_ermite_signature_proto_init() {
738+ if File_ermite_signature_proto != nil {
739+ return
740+ }
741+ type x struct{}
742+ out := protoimpl.TypeBuilder{
743+ File: protoimpl.DescBuilder{
744+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
745+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_ermite_signature_proto_rawDesc), len(file_ermite_signature_proto_rawDesc)),
746+ NumEnums: 2,
747+ NumMessages: 8,
748+ NumExtensions: 0,
749+ NumServices: 1,
750+ },
751+ GoTypes: file_ermite_signature_proto_goTypes,
752+ DependencyIndexes: file_ermite_signature_proto_depIdxs,
753+ EnumInfos: file_ermite_signature_proto_enumTypes,
754+ MessageInfos: file_ermite_signature_proto_msgTypes,
755+ }.Build()
756+ File_ermite_signature_proto = out.File
757+ file_ermite_signature_proto_goTypes = nil
758+ file_ermite_signature_proto_depIdxs = nil
759+}
M gen/ermite/types.pb.go +23 -9 generated file: collapsed
A proto/ermite/signature.proto +128 -0
@@ -0,0 +1,128 @@
1+// SPDX-License-Identifier: MIT
2+
3+syntax = "proto3";
4+
5+package ermite;
6+
7+import "google/protobuf/timestamp.proto";
8+
9+// SignatureFormat is the protocol of a commit signature.
10+enum SignatureFormat {
11+ // Not signed, or not set.
12+ SIGNATURE_FORMAT_UNSPECIFIED = 0;
13+ // Git SSH signature (gpg.format=ssh, "-----BEGIN SSH SIGNATURE-----").
14+ SIGNATURE_FORMAT_SSH = 1;
15+ // OpenPGP signature (gpg.format=openpgp, "-----BEGIN PGP SIGNATURE-----").
16+ SIGNATURE_FORMAT_GPG = 2;
17+ // X.509 (gpgsm) signature. Recognized, never verified.
18+ SIGNATURE_FORMAT_X509 = 3;
19+}
20+
21+// SignatureStatus is the outcome of checking the signature of a commit.
22+enum SignatureStatus {
23+ // The server did not check the commit (it could not be read).
24+ SIGNATURE_STATUS_UNSPECIFIED = 0;
25+ // The commit carries no signature.
26+ SIGNATURE_STATUS_UNSIGNED = 1;
27+ // Valid signature by a trusted key that is trusted for the committer email.
28+ SIGNATURE_STATUS_VERIFIED = 2;
29+ // Well-formed signature by a key the server does not trust.
30+ SIGNATURE_STATUS_UNKNOWN_KEY = 3;
31+ // The signature is malformed, does not match the commit, or uses a weak
32+ // hash (SHA-1 and older).
33+ SIGNATURE_STATUS_BAD_SIGNATURE = 4;
34+ // Valid signature by a trusted key that is not trusted for the committer
35+ // email.
36+ SIGNATURE_STATUS_EMAIL_MISMATCH = 5;
37+ // The OpenPGP key or signature had expired when the signature was made.
38+ SIGNATURE_STATUS_EXPIRED = 6;
39+ // The OpenPGP key is revoked.
40+ SIGNATURE_STATUS_REVOKED = 7;
41+ // The format is not verified by the server (X.509).
42+ SIGNATURE_STATUS_UNSUPPORTED = 8;
43+}
44+
45+// CommitVerification tells whether and how a commit is signed.
46+message CommitVerification {
47+ SignatureFormat format = 1;
48+ SignatureStatus status = 2;
49+ // Fingerprint of the signing key when the signature names one:
50+ // "SHA256:<base64>" for SSH, upper-case hex for OpenPGP (the 16-digit
51+ // issuer key id when the key is unknown).
52+ string fingerprint = 3;
53+ // KeyId is the id of the trusted key that matched; empty when none did.
54+ string key_id = 4;
55+ // KeyTitle is the title of the trusted key that matched.
56+ string key_title = 5;
57+}
58+
59+// TrustedKey is a public key whose signatures the server accepts for the
60+// listed committer emails.
61+message TrustedKey {
62+ // Id is the key fingerprint: "SHA256:<base64>" for SSH, the primary key
63+ // fingerprint in upper-case hex for OpenPGP.
64+ string id = 1;
65+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
66+ SignatureFormat format = 2;
67+ string title = 3;
68+ // PublicKey is "<type> <base64>" for SSH, the armored public key for
69+ // OpenPGP.
70+ string public_key = 4;
71+ // Emails are the committer emails the key may sign for, lower-case.
72+ repeated string emails = 5;
73+ google.protobuf.Timestamp created_at = 6;
74+ // Builtin is true for the server's own signing key
75+ // (ServerService.GetSigningKey): always trusted, cannot be removed.
76+ bool builtin = 7;
77+}
78+
79+// TrustedKeyService manages the keys commit signatures are checked against.
80+// Servers that implement it list "commit_signatures" in
81+// GetVersionResponse.features; their Commit messages then carry
82+// verification.
83+service TrustedKeyService {
84+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
85+ // caller may.
86+ rpc ListTrustedKeys(ListTrustedKeysRequest) returns (ListTrustedKeysResponse);
87+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
88+ // does not parse, a private key, no or too many emails; already_exists for
89+ // a key already listed; resource_exhausted beyond 100 keys.
90+ rpc AddTrustedKey(AddTrustedKeyRequest) returns (AddTrustedKeyResponse);
91+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
92+ // failed_precondition for the builtin key.
93+ rpc RemoveTrustedKey(RemoveTrustedKeyRequest) returns (RemoveTrustedKeyResponse);
94+}
95+
96+// ListTrustedKeysRequest is empty.
97+message ListTrustedKeysRequest {}
98+
99+// ListTrustedKeysResponse lists every trusted key.
100+message ListTrustedKeysResponse {
101+ repeated TrustedKey keys = 1;
102+}
103+
104+// AddTrustedKeyRequest describes the key to trust.
105+message AddTrustedKeyRequest {
106+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
107+ SignatureFormat format = 1;
108+ // Title is a label, 1 to 100 bytes.
109+ string title = 2;
110+ // PublicKey is an authorized_keys line for SSH, or an armored public key
111+ // block for OpenPGP (at most 64 KiB).
112+ string public_key = 3;
113+ // Emails are the committer emails the key may sign for, 1 to 10.
114+ repeated string emails = 4;
115+}
116+
117+// AddTrustedKeyResponse returns the stored key.
118+message AddTrustedKeyResponse {
119+ TrustedKey key = 1;
120+}
121+
122+// RemoveTrustedKeyRequest names the key to remove.
123+message RemoveTrustedKeyRequest {
124+ string id = 1;
125+}
126+
127+// RemoveTrustedKeyResponse is empty.
128+message RemoveTrustedKeyResponse {}
@@ -0,0 +1,128 @@
1+// SPDX-License-Identifier: MIT
2+
3+syntax = "proto3";
4+
5+package ermite;
6+
7+import "google/protobuf/timestamp.proto";
8+
9+// SignatureFormat is the protocol of a commit signature.
10+enum SignatureFormat {
11+ // Not signed, or not set.
12+ SIGNATURE_FORMAT_UNSPECIFIED = 0;
13+ // Git SSH signature (gpg.format=ssh, "-----BEGIN SSH SIGNATURE-----").
14+ SIGNATURE_FORMAT_SSH = 1;
15+ // OpenPGP signature (gpg.format=openpgp, "-----BEGIN PGP SIGNATURE-----").
16+ SIGNATURE_FORMAT_GPG = 2;
17+ // X.509 (gpgsm) signature. Recognized, never verified.
18+ SIGNATURE_FORMAT_X509 = 3;
19+}
20+
21+// SignatureStatus is the outcome of checking the signature of a commit.
22+enum SignatureStatus {
23+ // The server did not check the commit (it could not be read).
24+ SIGNATURE_STATUS_UNSPECIFIED = 0;
25+ // The commit carries no signature.
26+ SIGNATURE_STATUS_UNSIGNED = 1;
27+ // Valid signature by a trusted key that is trusted for the committer email.
28+ SIGNATURE_STATUS_VERIFIED = 2;
29+ // Well-formed signature by a key the server does not trust.
30+ SIGNATURE_STATUS_UNKNOWN_KEY = 3;
31+ // The signature is malformed, does not match the commit, or uses a weak
32+ // hash (SHA-1 and older).
33+ SIGNATURE_STATUS_BAD_SIGNATURE = 4;
34+ // Valid signature by a trusted key that is not trusted for the committer
35+ // email.
36+ SIGNATURE_STATUS_EMAIL_MISMATCH = 5;
37+ // The OpenPGP key or signature had expired when the signature was made.
38+ SIGNATURE_STATUS_EXPIRED = 6;
39+ // The OpenPGP key is revoked.
40+ SIGNATURE_STATUS_REVOKED = 7;
41+ // The format is not verified by the server (X.509).
42+ SIGNATURE_STATUS_UNSUPPORTED = 8;
43+}
44+
45+// CommitVerification tells whether and how a commit is signed.
46+message CommitVerification {
47+ SignatureFormat format = 1;
48+ SignatureStatus status = 2;
49+ // Fingerprint of the signing key when the signature names one:
50+ // "SHA256:<base64>" for SSH, upper-case hex for OpenPGP (the 16-digit
51+ // issuer key id when the key is unknown).
52+ string fingerprint = 3;
53+ // KeyId is the id of the trusted key that matched; empty when none did.
54+ string key_id = 4;
55+ // KeyTitle is the title of the trusted key that matched.
56+ string key_title = 5;
57+}
58+
59+// TrustedKey is a public key whose signatures the server accepts for the
60+// listed committer emails.
61+message TrustedKey {
62+ // Id is the key fingerprint: "SHA256:<base64>" for SSH, the primary key
63+ // fingerprint in upper-case hex for OpenPGP.
64+ string id = 1;
65+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
66+ SignatureFormat format = 2;
67+ string title = 3;
68+ // PublicKey is "<type> <base64>" for SSH, the armored public key for
69+ // OpenPGP.
70+ string public_key = 4;
71+ // Emails are the committer emails the key may sign for, lower-case.
72+ repeated string emails = 5;
73+ google.protobuf.Timestamp created_at = 6;
74+ // Builtin is true for the server's own signing key
75+ // (ServerService.GetSigningKey): always trusted, cannot be removed.
76+ bool builtin = 7;
77+}
78+
79+// TrustedKeyService manages the keys commit signatures are checked against.
80+// Servers that implement it list "commit_signatures" in
81+// GetVersionResponse.features; their Commit messages then carry
82+// verification.
83+service TrustedKeyService {
84+ // ListTrustedKeys lists the keys, the builtin key first. Any authenticated
85+ // caller may.
86+ rpc ListTrustedKeys(ListTrustedKeysRequest) returns (ListTrustedKeysResponse);
87+ // AddTrustedKey adds a key. Owner only. invalid_argument for a key that
88+ // does not parse, a private key, no or too many emails; already_exists for
89+ // a key already listed; resource_exhausted beyond 100 keys.
90+ rpc AddTrustedKey(AddTrustedKeyRequest) returns (AddTrustedKeyResponse);
91+ // RemoveTrustedKey removes a key. Owner only. not_found for an unknown id;
92+ // failed_precondition for the builtin key.
93+ rpc RemoveTrustedKey(RemoveTrustedKeyRequest) returns (RemoveTrustedKeyResponse);
94+}
95+
96+// ListTrustedKeysRequest is empty.
97+message ListTrustedKeysRequest {}
98+
99+// ListTrustedKeysResponse lists every trusted key.
100+message ListTrustedKeysResponse {
101+ repeated TrustedKey keys = 1;
102+}
103+
104+// AddTrustedKeyRequest describes the key to trust.
105+message AddTrustedKeyRequest {
106+ // Format is SIGNATURE_FORMAT_SSH or SIGNATURE_FORMAT_GPG.
107+ SignatureFormat format = 1;
108+ // Title is a label, 1 to 100 bytes.
109+ string title = 2;
110+ // PublicKey is an authorized_keys line for SSH, or an armored public key
111+ // block for OpenPGP (at most 64 KiB).
112+ string public_key = 3;
113+ // Emails are the committer emails the key may sign for, 1 to 10.
114+ repeated string emails = 4;
115+}
116+
117+// AddTrustedKeyResponse returns the stored key.
118+message AddTrustedKeyResponse {
119+ TrustedKey key = 1;
120+}
121+
122+// RemoveTrustedKeyRequest names the key to remove.
123+message RemoveTrustedKeyRequest {
124+ string id = 1;
125+}
126+
127+// RemoveTrustedKeyResponse is empty.
128+message RemoveTrustedKeyResponse {}
M proto/ermite/types.proto +4 -0
@@ -4,6 +4,7 @@ syntax = "proto3";
44
55 package ermite;
66
7+import "ermite/signature.proto";
78 import "google/protobuf/timestamp.proto";
89
910 // Signature identifies who did something in Git and when: the author or the
@@ -34,6 +35,9 @@ message Commit {
3435 // Message is the full commit message, including the summary. Text that is
3536 // not valid UTF-8 is converted with the replacement character.
3637 string message = 6;
38+ // Verification tells whether and how the commit is signed. Unset on
39+ // servers without the "commit_signatures" feature.
40+ CommitVerification verification = 7;
3741 }
3842
3943 // MergeMode is how a merge request is merged. Both modes need the target to
@@ -4,6 +4,7 @@ syntax = "proto3";
4 4
5 package ermite;5 package ermite;
6 6
7+import "ermite/signature.proto";
7 import "google/protobuf/timestamp.proto";8 import "google/protobuf/timestamp.proto";
8 9
9 // Signature identifies who did something in Git and when: the author or the10 // Signature identifies who did something in Git and when: the author or the
@@ -34,6 +35,9 @@ message Commit {
34 // Message is the full commit message, including the summary. Text that is35 // Message is the full commit message, including the summary. Text that is
35 // not valid UTF-8 is converted with the replacement character.36 // not valid UTF-8 is converted with the replacement character.
36 string message = 6;37 string message = 6;
38+ // Verification tells whether and how the commit is signed. Unset on
39+ // servers without the "commit_signatures" feature.
40+ CommitVerification verification = 7;
37 }41 }
38 42
39 // MergeMode is how a merge request is merged. Both modes need the target to43 // MergeMode is how a merge request is merged. Both modes need the target to

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close