aquaman-proxy 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Glue between `aquaman daemon` / the CLI and the OpenShell credential driver.
3
+ */
4
+ import * as path from 'node:path';
5
+ import { getConfigDir } from '../core/utils/config.js';
6
+ import { createOpenShellDriverCore } from './credential-driver.js';
7
+ import { startOpenShellDriverServer, loadGrpc } from './grpc-server.js';
8
+ /** macOS caps Unix socket paths at 104 bytes (Linux 108); bind fails above that. */
9
+ export const MAX_SOCKET_PATH = 103;
10
+ export function openshellDriverSocketPath(config) {
11
+ return config.openshell?.driver?.socketPath || path.join(getConfigDir(), 'openshell.sock');
12
+ }
13
+ /** True when the optional gRPC peers can be loaded. */
14
+ export async function grpcAvailable() {
15
+ try {
16
+ await loadGrpc();
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ /** The gateway TOML that points OpenShell at this driver. */
24
+ export function gatewayConfigSnippet(socketPath) {
25
+ return [
26
+ '[openshell.gateway]',
27
+ 'credential_drivers = ["aquaman"]',
28
+ '',
29
+ '[openshell.credential_drivers.aquaman]',
30
+ 'transport = "uds"',
31
+ `socket_path = "${socketPath}"`,
32
+ ].join('\n');
33
+ }
34
+ /**
35
+ * Resolves hand a value to the gateway (`read`); copy-mode writes and deletes
36
+ * change the vault (`rotate`). Validating a reference at create time hands
37
+ * nothing out, so only its refusals are recorded.
38
+ */
39
+ export function auditDriverAccess(audit, e) {
40
+ let operation;
41
+ if (e.op === 'resolve')
42
+ operation = 'read';
43
+ else if (e.mode === 'copy')
44
+ operation = 'rotate';
45
+ else if (!e.success)
46
+ operation = 'read';
47
+ else
48
+ return;
49
+ audit.logCredentialAccess('system', 'openshell', {
50
+ service: e.service,
51
+ operation,
52
+ success: e.success,
53
+ error: e.success ? undefined : `${e.ref}: ${e.error ?? 'refused'}`,
54
+ });
55
+ }
56
+ export async function startOpenShellDriver(opts) {
57
+ const socketPath = openshellDriverSocketPath(opts.config);
58
+ if (Buffer.byteLength(socketPath) > MAX_SOCKET_PATH) {
59
+ throw new Error(`socket path is ${Buffer.byteLength(socketPath)} bytes, over the ${MAX_SOCKET_PATH}-byte Unix socket limit: ${socketPath}. Set openshell.driver.socketPath to a shorter path.`);
60
+ }
61
+ const core = createOpenShellDriverCore({
62
+ store: opts.store,
63
+ scope: opts.scope,
64
+ version: opts.version,
65
+ onAccess: (e) => auditDriverAccess(opts.audit, e),
66
+ });
67
+ return startOpenShellDriverServer(core, socketPath);
68
+ }
69
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","sourceRoot":"","sources":["../../src/openshell/integration.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAA0B,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,QAAQ,EAA8B,MAAM,kBAAkB,CAAC;AAEpG,oFAAoF;AACpF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AAEnC,MAAM,UAAU,yBAAyB,CAAC,MAAqB;IAC7D,OAAO,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC7F,CAAC;AAED,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,QAAQ,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,OAAO;QACL,qBAAqB;QACrB,kCAAkC;QAClC,EAAE;QACF,wCAAwC;QACxC,mBAAmB;QACnB,kBAAkB,UAAU,GAAG;KAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAUD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,CAAoB;IACtE,IAAI,SAA4B,CAAC;IACjC,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;QAAE,SAAS,GAAG,MAAM,CAAC;SACtC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,SAAS,GAAG,QAAQ,CAAC;SAC5C,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,SAAS,GAAG,MAAM,CAAC;;QACnC,OAAO;IACZ,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE;QAC/C,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,SAAS;QACT,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,IAAI,SAAS,EAAE;KACnE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAM1C;IACC,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,eAAe,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,oBAAoB,eAAe,4BAA4B,UAAU,sDAAsD,CAAC,CAAC;IAClM,CAAC;IACD,MAAM,IAAI,GAAG,yBAAyB,CAAC;QACrC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;KAClD,CAAC,CAAC;IACH,OAAO,0BAA0B,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACtD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aquaman-proxy",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "🔱 API key protection for AI agents. Bring your own vault. Credentials stay where you already keep them, never in the agent's memory.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -51,7 +51,9 @@
51
51
  },
52
52
  "peerDependencies": {
53
53
  "argon2": "^0.45.1",
54
- "kdbxweb": "^2.1.1"
54
+ "kdbxweb": "^2.1.1",
55
+ "@grpc/grpc-js": "^1.14.5",
56
+ "@grpc/proto-loader": "^0.8.1"
55
57
  },
56
58
  "peerDependenciesMeta": {
57
59
  "argon2": {
@@ -59,15 +61,22 @@
59
61
  },
60
62
  "kdbxweb": {
61
63
  "optional": true
64
+ },
65
+ "@grpc/grpc-js": {
66
+ "optional": true
67
+ },
68
+ "@grpc/proto-loader": {
69
+ "optional": true
62
70
  }
63
71
  },
64
72
  "devDependencies": {
65
73
  "@types/node": "^20.19.43",
66
- "tsx": "^4.23.13",
74
+ "tsx": "^4.23.15",
67
75
  "typescript": "^5.3.0"
68
76
  },
69
77
  "files": [
70
78
  "dist",
79
+ "proto",
71
80
  "LICENSE",
72
81
  "README.md"
73
82
  ],
@@ -0,0 +1,9 @@
1
+ # OpenShell protocol files
2
+
3
+ Vendored unchanged from [NVIDIA/OpenShell](https://github.com/NVIDIA/OpenShell) at tag `v0.1.4`
4
+ (commit `5a7728c304b5528e954e9ae900cf21f84e1a12b1`), `proto/`. Apache-2.0, see the SPDX headers in
5
+ each file.
6
+
7
+ `aquaman daemon` loads them at runtime to serve the OpenShell external credential driver
8
+ (`credential_driver.proto`, extension protocol 1.0). Update them together with the CI lane's
9
+ OpenShell versions.
@@ -0,0 +1,146 @@
1
+ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ syntax = "proto3";
5
+
6
+ package openshell.credentials.v1;
7
+
8
+ import "datamodel.proto";
9
+ import "google/protobuf/timestamp.proto";
10
+ import "extension.proto";
11
+
12
+ // Internal credential-driver contract used by the gateway.
13
+ //
14
+ // The gateway owns provider semantics and sandbox delivery. Credential drivers
15
+ // own backend-specific storage, deletion, authentication, and lookup for
16
+ // gateway-managed provider-secret handles. Secrets include injectable provider
17
+ // credentials and gateway-only refresh material.
18
+ service CredentialDriver {
19
+ // Report driver identity and feature support.
20
+ rpc GetCapabilities(GetCredentialDriverCapabilitiesRequest)
21
+ returns (GetCredentialDriverCapabilitiesResponse);
22
+
23
+ // Store or overwrite one gateway-managed provider secret and return an opaque handle.
24
+ rpc StoreCredential(StoreCredentialRequest) returns (StoreCredentialResponse);
25
+
26
+ // Delete one provider credential handle.
27
+ rpc DeleteCredential(DeleteCredentialRequest) returns (DeleteCredentialResponse);
28
+
29
+ // Resolve a batch of credential handles into string secret values.
30
+ rpc ResolveCredentials(ResolveCredentialsRequest)
31
+ returns (ResolveCredentialsResponse);
32
+
33
+ // Optionally list discoverable credentials. Drivers may return UNIMPLEMENTED.
34
+ rpc ListCredentials(ListCredentialsRequest) returns (ListCredentialsResponse);
35
+ }
36
+
37
+ message GetCredentialDriverCapabilitiesRequest {
38
+ // Gateway protocol metadata. Drivers must reject unmet requirements.
39
+ openshell.extension.v1.PeerMetadata gateway = 1;
40
+ }
41
+
42
+ message GetCredentialDriverCapabilitiesResponse {
43
+ // Human-readable driver name.
44
+ string driver_name = 1;
45
+ // Deprecated diagnostic compatibility field. Use extension.implementation_version.
46
+ string driver_version = 2;
47
+ // Backend kind, such as "kubernetes-secrets" or "vault".
48
+ string backend_kind = 3;
49
+ // True when ListCredentials is supported.
50
+ bool supports_list = 4;
51
+ // True when ResolveCredentials may return expiration_time values.
52
+ bool supports_expires_at = 5;
53
+ // Credential-driver protocol metadata. Required for protocol negotiation.
54
+ // Declare protocol 1.0 and list "openshell.credentials.contract" in
55
+ // supported_capabilities.
56
+ openshell.extension.v1.PeerMetadata extension = 6;
57
+ }
58
+
59
+ message StoreCredentialRequest {
60
+ // Provider instance name supplied for audit and backend policy decisions.
61
+ string provider = 1;
62
+ // Gateway-owned logical key for this provider secret. Injectable credentials
63
+ // use their runtime environment key; refresh material uses an internal key.
64
+ string credential_key = 2;
65
+ // Secret value to store. Drivers must never log this field.
66
+ string value = 3;
67
+ // Existing handle to overwrite, if any.
68
+ openshell.datamodel.v1.CredentialHandle existing_handle = 4;
69
+ // Workspace that owns this provider. Used to ensure cross-workspace uniqueness.
70
+ string workspace = 5;
71
+ // Provider UUID. Combined with workspace to ensure globally unique backend paths.
72
+ string provider_id = 6;
73
+ // Per-write backend object identity. When empty, drivers use provider_id.
74
+ // Refreshes set this to a unique value so a staged write cannot overwrite the
75
+ // currently committed object while provider_id remains the immutable owner.
76
+ string object_id = 7;
77
+ }
78
+
79
+ message StoreCredentialResponse {
80
+ // Opaque handle for later resolution/deletion.
81
+ openshell.datamodel.v1.CredentialHandle handle = 1;
82
+ }
83
+
84
+ message DeleteCredentialRequest {
85
+ // Provider instance name supplied for audit and backend policy decisions.
86
+ string provider = 1;
87
+ // Gateway-owned logical key that owns the handle.
88
+ string credential_key = 2;
89
+ // Opaque handle to delete.
90
+ openshell.datamodel.v1.CredentialHandle handle = 3;
91
+ // Workspace that owns this provider. Used to ensure cross-workspace uniqueness.
92
+ string workspace = 4;
93
+ // Provider UUID. Combined with workspace to ensure globally unique backend paths.
94
+ string provider_id = 5;
95
+ }
96
+
97
+ message DeleteCredentialResponse {}
98
+
99
+ message ResolveCredentialsRequest {
100
+ repeated ResolveCredentialRequest credentials = 1;
101
+ }
102
+
103
+ message ResolveCredentialRequest {
104
+ // Gateway-chosen opaque ID used to correlate batch responses.
105
+ string request_id = 1;
106
+ // Provider instance name supplied for audit and backend policy decisions.
107
+ string provider = 2;
108
+ // Gateway-owned logical key for the value being resolved.
109
+ string credential_key = 3;
110
+ // Opaque handle to resolve.
111
+ openshell.datamodel.v1.CredentialHandle handle = 4;
112
+ // Workspace that owns this provider. Used to ensure cross-workspace uniqueness.
113
+ string workspace = 5;
114
+ // Provider UUID. Combined with workspace to ensure globally unique backend paths.
115
+ string provider_id = 6;
116
+ }
117
+
118
+ message ResolveCredentialsResponse {
119
+ repeated ResolvedCredential credentials = 1;
120
+ }
121
+
122
+ message ResolvedCredential {
123
+ reserved 3;
124
+ reserved "expires_at_ms";
125
+ // Echoes ResolveCredentialRequest.request_id.
126
+ string request_id = 1;
127
+ // Secret string value. Drivers must never log this field.
128
+ string value = 2;
129
+ // Expiration time. Absence means the credential does not expire.
130
+ google.protobuf.Timestamp expiration_time = 103;
131
+ }
132
+
133
+ message ListCredentialsRequest {}
134
+
135
+ message ListCredentialsResponse {
136
+ repeated ListedCredential credentials = 1;
137
+ }
138
+
139
+ message ListedCredential {
140
+ // Opaque handle identifier or driver-owned display name.
141
+ string handle = 1;
142
+ // Available credential keys under the backend object.
143
+ repeated string keys = 2;
144
+ // Driver-owned non-secret metadata.
145
+ map<string, string> metadata = 3;
146
+ }
@@ -0,0 +1,128 @@
1
+ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ syntax = "proto3";
5
+
6
+ package openshell.datamodel.v1;
7
+
8
+ import "options.proto";
9
+ import "google/protobuf/timestamp.proto";
10
+
11
+ // Selects the workspace scope for a public API request.
12
+ //
13
+ // Requests that operate on one workspace require a non-empty `workspace`.
14
+ // Cross-workspace list requests additionally accept `all_workspaces`. The
15
+ // containing request documents which selections it supports; an omitted
16
+ // selector is invalid for workspace-scoped operations.
17
+ message WorkspaceSelector {
18
+ oneof selection {
19
+ // One explicitly named workspace. Use `default` to select the gateway's
20
+ // default workspace; an empty name is invalid.
21
+ string workspace = 1;
22
+ // All workspaces the caller is authorized to access. Only supported by
23
+ // requests that explicitly document cross-workspace behavior.
24
+ AllWorkspaces all_workspaces = 2;
25
+ }
26
+ }
27
+
28
+ // Marker for the all-workspaces selector variant.
29
+ message AllWorkspaces {}
30
+
31
+ // Kubernetes-style metadata shared by all top-level OpenShell domain objects.
32
+ //
33
+ // This structure provides consistent metadata (identity, labels, annotations,
34
+ // timestamps, resource versioning) across Sandbox, Provider, SshSession, and
35
+ // other resources.
36
+ message ObjectMeta {
37
+ reserved 3, 8;
38
+ reserved "created_at_ms", "deletion_timestamp_ms";
39
+ // Stable object ID generated by the gateway.
40
+ string id = 1;
41
+
42
+ // Human-readable object name (unique per object type).
43
+ string name = 2;
44
+
45
+ // Time when the object was created.
46
+ google.protobuf.Timestamp created_time = 103;
47
+
48
+ // Key-value labels for filtering and organization.
49
+ // Labels must follow Kubernetes conventions: alphanumeric + `-._/`, max 63 chars per segment.
50
+ map<string, string> labels = 4;
51
+
52
+ // Optimistic concurrency control version.
53
+ // Incremented by the gateway on each update. Clients can use this for compare-and-swap operations.
54
+ uint64 resource_version = 5;
55
+
56
+ // Opaque key-value metadata that is not used for selectors.
57
+ // Annotation keys use the same qualified-key shape as labels, but values may be longer.
58
+ map<string, string> annotations = 6;
59
+
60
+ // Workspace that owns this resource. Empty is normalized to "default" by the
61
+ // gateway. Immutable after creation.
62
+ string workspace = 7;
63
+
64
+ // Time when graceful deletion was initiated. Absence means the object is
65
+ // not being deleted. Once set, this field is
66
+ // immutable — the only path forward is completing deletion.
67
+ google.protobuf.Timestamp deletion_time = 108;
68
+ }
69
+
70
+ // Phase of a workspace's lifecycle.
71
+ enum WorkspacePhase {
72
+ WORKSPACE_PHASE_UNSPECIFIED = 0;
73
+ WORKSPACE_PHASE_ACTIVE = 1;
74
+ WORKSPACE_PHASE_TERMINATING = 2;
75
+ }
76
+
77
+ // Status of a workspace.
78
+ message WorkspaceStatus {
79
+ WorkspacePhase phase = 1;
80
+ }
81
+
82
+ // Workspace resource. A hard isolation boundary for sandboxes, providers, and
83
+ // other workspace-scoped resources.
84
+ message Workspace {
85
+ // Kubernetes-style metadata (id, name, labels, timestamps, resource version).
86
+ // The workspace field in this ObjectMeta is unused (a workspace does not
87
+ // belong to another workspace).
88
+ ObjectMeta metadata = 1;
89
+
90
+ // Current lifecycle status.
91
+ WorkspaceStatus status = 2;
92
+ }
93
+
94
+ // Opaque handle for a provider credential stored by gateway credential storage.
95
+ // Handles are created by OpenShell and must not be authored by users.
96
+ message CredentialHandle {
97
+ // Internal storage owner or credential driver that owns this handle.
98
+ string driver = 1;
99
+ // Owner-owned opaque handle string.
100
+ string handle = 2;
101
+ // Owner-owned non-secret metadata.
102
+ map<string, string> metadata = 3;
103
+ }
104
+
105
+ // Provider model stored by OpenShell.
106
+ message Provider {
107
+ reserved 5;
108
+ reserved "credential_expires_at_ms";
109
+ // Kubernetes-style metadata (id, name, labels, timestamps, resource version).
110
+ ObjectMeta metadata = 1;
111
+ // ID of the provider profile this provider was created from, matched
112
+ // exactly (for example: "claude-code", "github").
113
+ string type = 2;
114
+ // Secret values used for authentication.
115
+ map<string, string> credentials = 3 [(openshell.options.v1.secret) = true];
116
+ // Non-secret provider configuration.
117
+ map<string, string> config = 4;
118
+ // Expiration times for credential values, keyed by credential/env var name.
119
+ // A missing key means the credential does not expire.
120
+ map<string, google.protobuf.Timestamp> credential_expiration_times = 105;
121
+ // Workspace where this provider's type profile is stored.
122
+ // Empty string = platform/global scope. Must be empty or match
123
+ // metadata.workspace; cross-workspace references are rejected.
124
+ string profile_workspace = 6;
125
+ // Opaque handles for secret values stored through gateway credential storage.
126
+ // This map is internal gateway state and is not accepted as user-authored input.
127
+ map<string, CredentialHandle> credential_handles = 7;
128
+ }
@@ -0,0 +1,34 @@
1
+ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ syntax = "proto3";
5
+
6
+ package openshell.extension.v1;
7
+
8
+ // Version of an OpenShell extension protocol contract.
9
+ //
10
+ // The major version changes when peers cannot safely interoperate. Minor
11
+ // versions add optional fields or capabilities and remain compatible when both
12
+ // peers' required capabilities are satisfied.
13
+ message ProtocolVersion {
14
+ uint32 major = 1;
15
+ uint32 minor = 2;
16
+ }
17
+
18
+ // Non-secret metadata exchanged by the gateway and an extension before use.
19
+ message PeerMetadata {
20
+ // Extension-family protocol contract version, distinct from the build.
21
+ ProtocolVersion protocol_version = 1;
22
+
23
+ // Stable human-readable implementation identity, such as "openshell/docker".
24
+ string implementation_name = 2;
25
+
26
+ // Implementation or build version used only for diagnostics.
27
+ string implementation_version = 3;
28
+
29
+ // Optional namespaced capabilities this peer understands.
30
+ repeated string supported_capabilities = 4;
31
+
32
+ // Capabilities that the opposite peer must advertise.
33
+ repeated string required_capabilities = 5;
34
+ }
@@ -0,0 +1,36 @@
1
+ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ syntax = "proto3";
5
+
6
+ package openshell.options.v1;
7
+
8
+ import "google/protobuf/descriptor.proto";
9
+
10
+ // Per-method authorization rule. Consumed at runtime by the gateway's
11
+ // descriptor-pool-based auth table to enforce auth mode, role, and scope.
12
+ message AuthorizationRule {
13
+ // Authentication mode: "bearer", "sandbox", "dual", "peer", "operator",
14
+ // or "unauthenticated". Operator requires a verified mTLS operator certificate.
15
+ string auth_mode = 1;
16
+ // Minimum workspace-level role required (checked by handler via
17
+ // authorize_workspace): "user" or "admin". Mutually exclusive with
18
+ // global_role.
19
+ string workspace_role = 2;
20
+ // Global role required (checked by middleware via OIDC claims):
21
+ // "platform_admin". Mutually exclusive with workspace_role.
22
+ string global_role = 3;
23
+ // Required OIDC scope on the bearer path (e.g. "sandbox:read").
24
+ string scope = 4;
25
+ }
26
+
27
+ extend google.protobuf.MethodOptions {
28
+ // Authorization metadata for a gRPC method.
29
+ AuthorizationRule authorization = 50000;
30
+ }
31
+
32
+ // Marks a protobuf field whose value must not cross generic observation or
33
+ // extension boundaries such as gateway interceptors.
34
+ extend google.protobuf.FieldOptions {
35
+ bool secret = 50001;
36
+ }