diff --git a/module/WORK_CONTEXTS.md b/module/WORK_CONTEXTS.md index 5d7ef077e..ba4838ad8 100644 --- a/module/WORK_CONTEXTS.md +++ b/module/WORK_CONTEXTS.md @@ -187,6 +187,18 @@ The mode is the binding's, never the request's. The chain-preserving exchange, StartTask and registered-agent actors are unchanged, and a binding without a mode keeps its owner-only child. +**A parent that names its module's bindings.** A person's parent for a module +that will exchange through its installed bindings may name those bindings +instead of their scopes: `StartTask`'s `operation_bindings` takes binding ids +of the audience module. The host resolves each one the way the exchange will +(`ModuleOperationAudience`: the binding as installed at the organization, +narrowed by that installation) and adds its invoke scopes, keeping each +resource only if the person holds it by the check every mint makes. A binding +the person holds nothing under is refused by name. So a source binding's ids +come from the organization's installation, never from the caller. Only a +direct human-owned mint takes it; an actor's mint and a resource-confined mint +refuse it. A scope the caller also names is carried once. + Resource kinds, actions and resource ids are sorted and unique; wildcards are refused. Lookup scopes are optional: a binding that declares only invoke scopes redeems no lookup, and a lookup exchange under it is refused by name. When present, diff --git a/module/contracts/api/accounts/authority/contract.binpb b/module/contracts/api/accounts/authority/contract.binpb index 590c0a8eb..9e7aba42a 100644 Binary files a/module/contracts/api/accounts/authority/contract.binpb and b/module/contracts/api/accounts/authority/contract.binpb differ diff --git a/module/contracts/api/accounts/authority/proto/saas/accounts/v1/work_contexts.proto b/module/contracts/api/accounts/authority/proto/saas/accounts/v1/work_contexts.proto index c5db6a13c..7b8356d96 100644 --- a/module/contracts/api/accounts/authority/proto/saas/accounts/v1/work_contexts.proto +++ b/module/contracts/api/accounts/authority/proto/saas/accounts/v1/work_contexts.proto @@ -91,6 +91,20 @@ message StartTaskWorkContextRequest { (buf.validate.field).string.min_len = 1, (buf.validate.field).string.max_len = 512 ]; + // Operation bindings of the audience module, by name, whose invoke scopes + // this capability carries beside authority_scopes. The host resolves each + // name to the binding as installed at org_id, narrowed by that installation + // exactly as the module's delegated exchange redeems it, and keeps each + // resource only if the person holds it. The caller names a binding and never + // its resource ids. A direct human-owned mint only. + repeated string operation_bindings = 11 [ + (buf.validate.field).repeated.max_items = 64, + (buf.validate.field).repeated.unique = true, + (buf.validate.field).repeated.items.string = { + min_len: 1 + max_len: 256 + } + ]; } // StartInstallationTaskRequest is the headless (no-user-present) mint path. The diff --git a/module/contracts/api/accounts/connect/contract.binpb b/module/contracts/api/accounts/connect/contract.binpb index 590c0a8eb..9e7aba42a 100644 Binary files a/module/contracts/api/accounts/connect/contract.binpb and b/module/contracts/api/accounts/connect/contract.binpb differ diff --git a/module/contracts/api/accounts/connect/proto/saas/accounts/v1/work_contexts.proto b/module/contracts/api/accounts/connect/proto/saas/accounts/v1/work_contexts.proto index c5db6a13c..7b8356d96 100644 --- a/module/contracts/api/accounts/connect/proto/saas/accounts/v1/work_contexts.proto +++ b/module/contracts/api/accounts/connect/proto/saas/accounts/v1/work_contexts.proto @@ -91,6 +91,20 @@ message StartTaskWorkContextRequest { (buf.validate.field).string.min_len = 1, (buf.validate.field).string.max_len = 512 ]; + // Operation bindings of the audience module, by name, whose invoke scopes + // this capability carries beside authority_scopes. The host resolves each + // name to the binding as installed at org_id, narrowed by that installation + // exactly as the module's delegated exchange redeems it, and keeps each + // resource only if the person holds it. The caller names a binding and never + // its resource ids. A direct human-owned mint only. + repeated string operation_bindings = 11 [ + (buf.validate.field).repeated.max_items = 64, + (buf.validate.field).repeated.unique = true, + (buf.validate.field).repeated.items.string = { + min_len: 1 + max_len: 256 + } + ]; } // StartInstallationTaskRequest is the headless (no-user-present) mint path. The diff --git a/module/contracts/api/catalog.codefly.json b/module/contracts/api/catalog.codefly.json index 5a4135c62..677541b10 100644 --- a/module/contracts/api/catalog.codefly.json +++ b/module/contracts/api/catalog.codefly.json @@ -10,7 +10,7 @@ "kind": "protobuf", "package": "saas.accounts.v1", "path": "contracts/api/accounts/authority/contract.binpb", - "digest": "sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7", + "digest": "sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c", "services": [ { "name": "ModuleCapabilitiesService", @@ -65,7 +65,7 @@ "kind": "protobuf", "package": "saas.accounts.v1", "path": "contracts/api/accounts/connect/contract.binpb", - "digest": "sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7", + "digest": "sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c", "services": [ { "name": "APIKeyService", diff --git a/module/module.package.codefly.yaml b/module/module.package.codefly.yaml index 34ea2ee34..d0b76c941 100644 --- a/module/module.package.codefly.yaml +++ b/module/module.package.codefly.yaml @@ -18,12 +18,12 @@ services: kind: protobuf package: saas.accounts.v1 path: contracts/api/accounts/authority/contract.binpb - digest: sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7 + digest: sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c - endpoint: connect kind: protobuf package: saas.accounts.v1 path: contracts/api/accounts/connect/contract.binpb - digest: sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7 + digest: sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c - name: auth-gateway endpoints: [grpc, rest] api-contracts: diff --git a/module/services/accounts/code/pkg/adapters/start_task_operation_bindings.go b/module/services/accounts/code/pkg/adapters/start_task_operation_bindings.go new file mode 100644 index 000000000..14dd0d9ab --- /dev/null +++ b/module/services/accounts/code/pkg/adapters/start_task_operation_bindings.go @@ -0,0 +1,121 @@ +package adapters + +import ( + "context" + "slices" + + accountsauth "accounts/pkg/auth" + "accounts/pkg/business" + gen "accounts/pkg/gen/saas/accounts/v1" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// requireOperationBindingMint refuses operation_bindings outside the one shape +// that takes them: a direct human-owned mint. An actor's ceiling and a confined +// credential's consumer ceiling are decided on the scopes a caller names, so +// neither is widened by a name resolved here. +func requireOperationBindingMint(ctx context.Context, req *gen.StartTaskWorkContextRequest) error { + if len(req.GetOperationBindings()) == 0 { + return nil + } + if req.GetActorPrincipalId() != "" { + return status.Error(codes.InvalidArgument, "operation_bindings is for a direct human-owned mint, not an actor's") + } + if _, confined := accountsauth.VerifiedResourceConfinement(ctx); confined { + return status.Error(codes.InvalidArgument, "operation_bindings is refused on a resource-confined mint") + } + if service == nil { + return status.Error(codes.Unavailable, "module authority unavailable") + } + return nil +} + +// withOperationBindingScopes adds the invoke scopes of each named operation +// binding of the audience module to the scopes a caller asked for. +// +// A name resolves through service.ModuleOperationAudience, the resolution the +// module's delegated exchange redeems the binding through: the binding as +// installed at the organisation, narrowed by that installation. So the resource +// ids come from the installation, never from the caller, and the capability +// carries exactly what the exchange will ask of it. Each resource is kept only +// if the person holds it, by the same check every mint makes; a binding the +// person holds nothing under is refused by name. A scope the caller already +// named is not added twice. +func (s *WorkContextAuthorityServer) withOperationBindingScopes(ctx context.Context, orgID, audience string, asked []*gen.WorkContextScope, names []string) ([]*gen.WorkContextScope, error) { + ownerID, err := s.authorizeOwner(ctx, orgID) + if err != nil { + return nil, err + } + module := business.ModuleCaller{PrincipalID: business.ModulePrincipalID(audience), BoundOrg: orgID} + out := slices.Clone(asked) + for _, name := range names { + binding, err := service.ModuleOperationAudience(ctx, module, orgID, audience, name) + if err != nil { + return nil, err + } + held := 0 + for _, scope := range binding.InvokeScopes { + kept, err := s.heldBindingScope(ctx, orgID, ownerID, audience, scope) + if err != nil { + return nil, err + } + if kept == nil { + continue + } + held++ + if !slices.ContainsFunc(out, func(existing *gen.WorkContextScope) bool { return proto.Equal(existing, kept) }) { + out = append(out, kept) + } + } + if held == 0 { + return nil, status.Errorf(codes.PermissionDenied, "the person holds nothing under operation binding %q", name) + } + } + return out, nil +} + +// heldBindingScope is the part of one binding scope the person holds: every +// action of the scope, on each resource it names, or on its kind when it names +// none. Nil when the person holds none of it. +func (s *WorkContextAuthorityServer) heldBindingScope(ctx context.Context, orgID, ownerID, audience string, scope business.ModuleOperationScope) (*gen.WorkContextScope, error) { + candidate := func(ids []string) *gen.WorkContextScope { + return &gen.WorkContextScope{ResourceKind: scope.ResourceKind, Actions: slices.Clone(scope.Actions), ResourceIds: ids} + } + holds := func(c *gen.WorkContextScope) (bool, error) { + permissions, _, err := workContextScopes([]*gen.WorkContextScope{c}, mintContentReads(audience)) + if err != nil { + return false, status.Error(codes.Internal, err.Error()) + } + _, err = s.resolveAuthority(ctx, orgID, ownerID, "", permissions) + switch status.Code(err) { + case codes.OK: + return true, nil + case codes.PermissionDenied: + return false, nil + } + return false, err + } + if len(scope.ResourceIDs) == 0 { + if ok, err := holds(candidate(nil)); !ok || err != nil { + return nil, err + } + return candidate(nil), nil + } + var ids []string + for _, id := range scope.ResourceIDs { + ok, err := holds(candidate([]string{id})) + if err != nil { + return nil, err + } + if ok { + ids = append(ids, id) + } + } + if len(ids) == 0 { + return nil, nil + } + return candidate(ids), nil +} diff --git a/module/services/accounts/code/pkg/adapters/start_task_operation_bindings_test.go b/module/services/accounts/code/pkg/adapters/start_task_operation_bindings_test.go new file mode 100644 index 000000000..b06b2ebad --- /dev/null +++ b/module/services/accounts/code/pkg/adapters/start_task_operation_bindings_test.go @@ -0,0 +1,105 @@ +package adapters + +import ( + "context" + "maps" + "testing" + + "accounts/pkg/auth" + "accounts/pkg/business" + gen "accounts/pkg/gen/saas/accounts/v1" + + corework "github.com/codefly-dev/core/workcontext" + "github.com/google/uuid" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var bindingRunScope = []*gen.WorkContextScope{{ResourceKind: "runs", Actions: []string{"execute"}}} + +func (c moduleActorCase) startTaskNaming(bindings ...string) (*gen.IssuedWorkContext, error) { + caller := stampVerifiedIdentity(context.Background(), readOwner, readOrg, auth.Assurance{}) + return c.server.StartTask(caller, &gen.StartTaskWorkContextRequest{ + OrgId: readOrg, TaskId: uuid.NewString(), Audience: "reader", + AuthorityScopes: bindingRunScope, OperationBindings: bindings, + }) +} + +// A parent that names its module's binding carries that binding's installed +// scopes, resource ids included, without the caller naming them; and the +// module's exchange of that binding redeems it. +func TestStartTaskCarriesANamedBindingAsInstalled(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + parent, err := c.startTaskNaming("act-source") + require.NoError(t, err) + decoded, err := corework.Decode(parent.Token) + require.NoError(t, err) + scopes := wireScopes(decoded.Context().AuthorityScopes) + require.Len(t, scopes, 2) + require.Equal(t, "runs", scopes[0].ResourceKind) + require.Equal(t, business.SourceOperationResourceKind, scopes[1].ResourceKind) + require.Equal(t, []string{"invoke", "read"}, scopes[1].Actions) + require.Equal(t, []string{actorSource}, scopes[1].ResourceIds) + + issued, err := c.exchange("act-source", parent.Token, c.moduleToken, false) + require.NoError(t, err) + child, err := corework.Decode(issued.Token) + require.NoError(t, err) + require.Equal(t, []string{actorSource}, child.Context().ActorChain[0].GrantedScopes[0].ResourceIds) +} + +// A caller that also names the binding's scope gets it once. +func TestStartTaskDoesNotRepeatANamedScope(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + caller := stampVerifiedIdentity(context.Background(), readOwner, readOrg, auth.Assurance{}) + explicit := append(append([]*gen.WorkContextScope(nil), bindingRunScope...), + &gen.WorkContextScope{ResourceKind: business.SourceOperationResourceKind, Actions: []string{"invoke", "read"}, ResourceIds: []string{actorSource}}) + parent, err := c.server.StartTask(caller, &gen.StartTaskWorkContextRequest{ + OrgId: readOrg, TaskId: uuid.NewString(), Audience: "reader", AuthorityScopes: explicit, OperationBindings: []string{"act-source"}, + }) + require.NoError(t, err) + decoded, err := corework.Decode(parent.Token) + require.NoError(t, err) + require.Len(t, decoded.Context().AuthorityScopes, 2) +} + +func TestStartTaskOperationBindingRefusals(t *testing.T) { + t.Run("a binding the module is not installed with", func(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + _, err := c.startTaskNaming("no-such-binding") + require.Equal(t, codes.PermissionDenied, status.Code(err)) + require.Contains(t, status.Convert(err).Message(), "installed operation audience required") + }) + t.Run("an installation narrowed away from the binding's sources", func(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + live := c.f.live[business.ModulePrincipalID("reader")] + scope := live.Scope + scope.Follows = false + scope.OperationAudiences = maps.Clone(scope.OperationAudiences) + narrowed := scope.OperationAudiences["act-source"] + elsewhere := []business.ModuleOperationScope{{ResourceKind: business.SourceOperationResourceKind, Actions: []string{"invoke", "read"}, ResourceIDs: []string{"source-b"}}} + narrowed.InvokeScopes, narrowed.LookupScopes = elsewhere, elsewhere + scope.OperationAudiences["act-source"] = narrowed + live.Scope = scope + _, err := c.startTaskNaming("act-source") + require.Equal(t, codes.PermissionDenied, status.Code(err)) + require.Contains(t, status.Convert(err).Message(), "installed operation audience required") + }) + t.Run("a binding the person holds nothing under, refused by name", func(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + c.server.authority = sourceAccessWithdrawn{} + _, err := c.startTaskNaming("act-source") + require.Equal(t, codes.PermissionDenied, status.Code(err)) + require.Contains(t, status.Convert(err).Message(), `"act-source"`) + }) + t.Run("an actor's mint", func(t *testing.T) { + c := moduleActorFixture(t, moduleActorScopes) + caller := stampVerifiedIdentity(context.Background(), readOwner, readOrg, auth.Assurance{}) + _, err := c.server.StartTask(caller, &gen.StartTaskWorkContextRequest{ + OrgId: readOrg, TaskId: uuid.NewString(), Audience: "reader", ActorPrincipalId: uuid.NewString(), + AuthorityScopes: bindingRunScope, OperationBindings: []string{"act-source"}, + }) + require.Equal(t, codes.InvalidArgument, status.Code(err)) + }) +} diff --git a/module/services/accounts/code/pkg/adapters/work_context_rpcs.go b/module/services/accounts/code/pkg/adapters/work_context_rpcs.go index debe897a8..8a833604f 100644 --- a/module/services/accounts/code/pkg/adapters/work_context_rpcs.go +++ b/module/services/accounts/code/pkg/adapters/work_context_rpcs.go @@ -541,6 +541,10 @@ func (s *WorkContextAuthorityServer) StartTask( if err := requireVocabularyAudience(ctx, req.GetAudience()); err != nil { return nil, err } + if err := requireOperationBindingMint(ctx, req); err != nil { + return nil, err + } + authorityScopes := req.GetAuthorityScopes() eligible := mintContentReads(req.GetAudience()) var standing []string if service != nil && req.GetActorPrincipalId() == "" { @@ -551,8 +555,15 @@ func (s *WorkContextAuthorityServer) StartTask( return nil, err } defer release() + // Inside the authority span, so the installation the bindings resolve + // against is the one this capability is signed under. + if names := req.GetOperationBindings(); len(names) > 0 { + if authorityScopes, err = s.withOperationBindingScopes(ctx, req.GetOrgId(), req.GetAudience(), authorityScopes, names); err != nil { + return nil, err + } + } var kinds []string - for _, scope := range req.GetAuthorityScopes() { + for _, scope := range authorityScopes { if len(scope.GetActions()) == 1 && scope.GetActions()[0] == "read" { kinds = append(kinds, scope.GetResourceKind()) } @@ -565,7 +576,7 @@ func (s *WorkContextAuthorityServer) StartTask( direct := eligible eligible = func(kind string) bool { return direct(kind) || slices.Contains(foreign, kind) } } - permissions, scopes, err := workContextScopes(req.GetAuthorityScopes(), eligible) + permissions, scopes, err := workContextScopes(authorityScopes, eligible) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) } diff --git a/module/services/accounts/code/pkg/gen/saas/accounts/v1/work_contexts.pb.go b/module/services/accounts/code/pkg/gen/saas/accounts/v1/work_contexts.pb.go index 6de6b4e1a..5a8113a74 100644 --- a/module/services/accounts/code/pkg/gen/saas/accounts/v1/work_contexts.pb.go +++ b/module/services/accounts/code/pkg/gen/saas/accounts/v1/work_contexts.pb.go @@ -173,9 +173,16 @@ type StartTaskWorkContextRequest struct { // capability to this exact workspace and reject cross-workspace reuse. WorkspaceId *string `protobuf:"bytes,9,opt,name=workspace_id,json=workspaceId,proto3,oneof" json:"workspace_id,omitempty"` // Optional product/project attribution inside workspace_id. - ProjectId *string `protobuf:"bytes,10,opt,name=project_id,json=projectId,proto3,oneof" json:"project_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + ProjectId *string `protobuf:"bytes,10,opt,name=project_id,json=projectId,proto3,oneof" json:"project_id,omitempty"` + // Operation bindings of the audience module, by name, whose invoke scopes + // this capability carries beside authority_scopes. The host resolves each + // name to the binding as installed at org_id, narrowed by that installation + // exactly as the module's delegated exchange redeems it, and keeps each + // resource only if the person holds it. The caller names a binding and never + // its resource ids. A direct human-owned mint only. + OperationBindings []string `protobuf:"bytes,11,rep,name=operation_bindings,json=operationBindings,proto3" json:"operation_bindings,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StartTaskWorkContextRequest) Reset() { @@ -271,6 +278,13 @@ func (x *StartTaskWorkContextRequest) GetProjectId() string { return "" } +func (x *StartTaskWorkContextRequest) GetOperationBindings() []string { + if x != nil { + return x.OperationBindings + } + return nil +} + // StartInstallationTaskRequest is the headless (no-user-present) mint path. The // caller is a trusted internal service (a job consumer leasing an ingest job), // not a bearer: owner := the installation's owner of record; actor := the agent @@ -1201,7 +1215,7 @@ const file_saas_accounts_v1_work_contexts_proto_rawDesc = "" + "\rresource_kind\x18\x01 \x01(\tB\n" + "\xbaH\ar\x05\x10\x01\x18\x80\x01R\fresourceKind\x12/\n" + "\aactions\x18\x02 \x03(\tB\x15\xbaH\x12\x92\x01\x0f\b\x01\x10@\x18\x01\"\ar\x05\x10\x01\x18\x80\x01R\aactions\x127\n" + - "\fresource_ids\x18\x03 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x80\x02\x18\x01\"\ar\x05\x10\x01\x18\x80\x04R\vresourceIds\"\xa8\x04\n" + + "\fresource_ids\x18\x03 \x03(\tB\x14\xbaH\x11\x92\x01\x0e\x10\x80\x02\x18\x01\"\ar\x05\x10\x01\x18\x80\x04R\vresourceIds\"\xec\x04\n" + "\x1bStartTaskWorkContextRequest\x12\x1f\n" + "\x06org_id\x18\x01 \x01(\tB\b\xbaH\x05r\x03\xb0\x01\x01R\x05orgId\x12$\n" + "\atask_id\x18\x02 \x01(\tB\v\xbaH\b\xd8\x01\x01r\x03\xb0\x01\x01R\x06taskId\x12,\n" + @@ -1219,7 +1233,8 @@ const file_saas_accounts_v1_work_contexts_proto_rawDesc = "" + "\n" + "project_id\x18\n" + " \x01(\tB\n" + - "\xbaH\ar\x05\x10\x01\x18\x80\x04H\x01R\tprojectId\x88\x01\x01B\x0f\n" + + "\xbaH\ar\x05\x10\x01\x18\x80\x04H\x01R\tprojectId\x88\x01\x01\x12B\n" + + "\x12operation_bindings\x18\v \x03(\tB\x13\xbaH\x10\x92\x01\r\x10@\x18\x01\"\ar\x05\x10\x01\x18\x80\x02R\x11operationBindingsB\x0f\n" + "\r_workspace_idB\r\n" + "\v_project_idJ\x04\b\x03\x10\x04R\n" + "session_id\"\xab\x04\n" + diff --git a/module/services/accounts/generated/openapi-raw/api.swagger.json b/module/services/accounts/generated/openapi-raw/api.swagger.json index 92a8f0b83..1beb48c30 100644 --- a/module/services/accounts/generated/openapi-raw/api.swagger.json +++ b/module/services/accounts/generated/openapi-raw/api.swagger.json @@ -11870,6 +11870,13 @@ "projectId": { "type": "string", "description": "Optional product/project attribution inside workspace_id." + }, + "operationBindings": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Operation bindings of the audience module, by name, whose invoke scopes\nthis capability carries beside authority_scopes. The host resolves each\nname to the binding as installed at org_id, narrowed by that installation\nexactly as the module's delegated exchange redeems it, and keeps each\nresource only if the person holds it. The caller names a binding and never\nits resource ids. A direct human-owned mint only." } }, "description": "StartTaskWorkContextRequest mints a Task capability for the caller. Its Session\nis the one the caller authenticated with — or a fresh one when it has none —\nassigned by the issuer and returned in IssuedWorkContext, never named by the\ncaller: a session a caller could name is one it could name after another\ncredential's, and a confined credential is paired with a capability on the\nsession alone." diff --git a/module/services/accounts/openapi/api.swagger.json b/module/services/accounts/openapi/api.swagger.json index 9fb8507fd..66859d30b 100644 --- a/module/services/accounts/openapi/api.swagger.json +++ b/module/services/accounts/openapi/api.swagger.json @@ -5362,6 +5362,13 @@ }, "type": "array" }, + "operationBindings": { + "description": "Operation bindings of the audience module, by name, whose invoke scopes\nthis capability carries beside authority_scopes. The host resolves each\nname to the binding as installed at org_id, narrowed by that installation\nexactly as the module's delegated exchange redeems it, and keeps each\nresource only if the person holds it. The caller names a binding and never\nits resource ids. A direct human-owned mint only.", + "items": { + "type": "string" + }, + "type": "array" + }, "orgId": { "type": "string" }, diff --git a/module/services/accounts/proto/saas/accounts/v1/work_contexts.proto b/module/services/accounts/proto/saas/accounts/v1/work_contexts.proto index c5db6a13c..7b8356d96 100644 --- a/module/services/accounts/proto/saas/accounts/v1/work_contexts.proto +++ b/module/services/accounts/proto/saas/accounts/v1/work_contexts.proto @@ -91,6 +91,20 @@ message StartTaskWorkContextRequest { (buf.validate.field).string.min_len = 1, (buf.validate.field).string.max_len = 512 ]; + // Operation bindings of the audience module, by name, whose invoke scopes + // this capability carries beside authority_scopes. The host resolves each + // name to the binding as installed at org_id, narrowed by that installation + // exactly as the module's delegated exchange redeems it, and keeps each + // resource only if the person holds it. The caller names a binding and never + // its resource ids. A direct human-owned mint only. + repeated string operation_bindings = 11 [ + (buf.validate.field).repeated.max_items = 64, + (buf.validate.field).repeated.unique = true, + (buf.validate.field).repeated.items.string = { + min_len: 1 + max_len: 256 + } + ]; } // StartInstallationTaskRequest is the headless (no-user-present) mint path. The diff --git a/module/services/frontend/code/packages/saas-sdk/generated/contract/catalog.codefly.json b/module/services/frontend/code/packages/saas-sdk/generated/contract/catalog.codefly.json index 363d105db..acf77f39d 100644 --- a/module/services/frontend/code/packages/saas-sdk/generated/contract/catalog.codefly.json +++ b/module/services/frontend/code/packages/saas-sdk/generated/contract/catalog.codefly.json @@ -10,7 +10,7 @@ "kind": "protobuf", "package": "saas.accounts.v1", "path": "contract.binpb", - "digest": "sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7", + "digest": "sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c", "services": [ { "name": "APIKeyService", diff --git a/module/services/frontend/code/packages/saas-sdk/generated/contract/contract.binpb b/module/services/frontend/code/packages/saas-sdk/generated/contract/contract.binpb index 590c0a8eb..9e7aba42a 100644 Binary files a/module/services/frontend/code/packages/saas-sdk/generated/contract/contract.binpb and b/module/services/frontend/code/packages/saas-sdk/generated/contract/contract.binpb differ diff --git a/module/services/frontend/code/packages/saas-sdk/generated/library.codefly.yaml b/module/services/frontend/code/packages/saas-sdk/generated/library.codefly.yaml index e907bd78a..e4ae5d3e4 100644 --- a/module/services/frontend/code/packages/saas-sdk/generated/library.codefly.yaml +++ b/module/services/frontend/code/packages/saas-sdk/generated/library.codefly.yaml @@ -12,7 +12,7 @@ sources: module: saas-starter service: accounts endpoint: connect - contract-digest: sha256:373a8f3a22b7968c36dd9faffb9be5ef64213b1de2a532f5e567007bd65caaa7 + contract-digest: sha256:21f848eb59ce4aca4903d354b66131c8e9595771d505d762fa07e730f32c4c4c services: - APIKeyService - AccessibleScopeService @@ -52,6 +52,6 @@ sources: - WorkContextService as: accounts generated-by: - codefly: 0.1.191 + codefly: 0.1.185 companion: ghcr.io/codefly-dev/proto:0.0.16 facade: true diff --git a/module/services/frontend/code/packages/saas-sdk/generated/typescript/src/gen/saas/accounts/v1/work_contexts_pb.ts b/module/services/frontend/code/packages/saas-sdk/generated/typescript/src/gen/saas/accounts/v1/work_contexts_pb.ts index 94cbce45c..0d7e2a687 100644 --- a/module/services/frontend/code/packages/saas-sdk/generated/typescript/src/gen/saas/accounts/v1/work_contexts_pb.ts +++ b/module/services/frontend/code/packages/saas-sdk/generated/typescript/src/gen/saas/accounts/v1/work_contexts_pb.ts @@ -15,7 +15,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file saas/accounts/v1/work_contexts.proto. */ export const file_saas_accounts_v1_work_contexts: GenFile = /*@__PURE__*/ - fileDesc("CiRzYWFzL2FjY291bnRzL3YxL3dvcmtfY29udGV4dHMucHJvdG8SEHNhYXMuYWNjb3VudHMudjEiiQEKEFdvcmtDb250ZXh0U2NvcGUSIQoNcmVzb3VyY2Vfa2luZBgBIAEoCUIKukgHcgUQARiAARImCgdhY3Rpb25zGAIgAygJQhW6SBKSAQ8IARBAGAEiB3IFEAEYgAESKgoMcmVzb3VyY2VfaWRzGAMgAygJQhS6SBGSAQ4QgAIYASIHcgUQARiABCK6AwobU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHAoHdGFza19pZBgCIAEoCUILukgI2AEBcgOwAQESGgoSYWN0b3JfcHJpbmNpcGFsX2lkGAQgASgJEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBQg8KDV93b3Jrc3BhY2VfaWRCDQoLX3Byb2plY3RfaWRKBAgDEARSCnNlc3Npb25faWQivwMKHFN0YXJ0SW5zdGFsbGF0aW9uVGFza1JlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIhCg9pbnN0YWxsYXRpb25faWQYAiABKAlCCLpIBXIDsAEBEhkKB3Rhc2tfaWQYAyABKAlCCLpIBXIDsAEBEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBQg8KDV93b3Jrc3BhY2VfaWRCDQoLX3Byb2plY3RfaWRKBAgEEAVSCnNlc3Npb25faWQijQIKIlN0YXJ0Um9vdFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIcCgpzZXNzaW9uX2lkGAMgASgJQgi6SAVyA7ABARIcCghhdWRpZW5jZRgEIAEoCUIKukgHcgUQARiABBJACg1yZXBsYXlfcG9saWN5GAUgASgOMikuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJlcGxheVBvbGljeRIfCgt0dGxfc2Vjb25kcxgGIAEoBUIKukgHGgUYhAcoACK6AgoiRXhjaGFuZ2VXb3JrQ29udGV4dEF1ZGllbmNlUmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEhwKCGF1ZGllbmNlGAMgASgJQgq6SAdyBRABGIAEEkkKEWF0dGVudWF0ZWRfc2NvcGVzGAQgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEkAKDXJlcGxheV9wb2xpY3kYBSABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAYgASgFQgq6SAcaBRiEBygAIvACCiNTdGFydENoaWxkU2Vzc2lvbldvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEiQKEmFjdG9yX3ByaW5jaXBhbF9pZBgEIAEoCUIIukgFcgOwAQESRgoOZ3JhbnRlZF9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKABKBAgDEARSCnNlc3Npb25faWQivwIKF1JlbmV3V29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESLgoZcGFyZW50X3dvcmtfY29udGV4dF90b2tlbhgCIAEoCUILukgIcgYQARiAgAISIQoIYXVkaWVuY2UYAyABKAlCCrpIB3IFEAEYgARIAIgBARJHChFhdHRlbnVhdGVkX3Njb3BlcxgEIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIIukgFkgECEEASQAoNcmVwbGF5X3BvbGljeRgFIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYBiABKAVCCrpIBxoFGIQHKABCCwoJX2F1ZGllbmNlIvECChFJc3N1ZWRXb3JrQ29udGV4dBINCgV0b2tlbhgBIAEoCRIOCgZvcmdfaWQYAiABKAkSGgoSb3duZXJfcHJpbmNpcGFsX2lkGAMgASgJEg8KB3Rhc2tfaWQYBCABKAkSEgoKc2Vzc2lvbl9pZBgFIAEoCRIeChFwYXJlbnRfc2Vzc2lvbl9pZBgGIAEoCUgAiAEBEiIKGmN1cnJlbnRfYWN0b3JfcHJpbmNpcGFsX2lkGAcgASgJEh4KFmF1dGhvcml6YXRpb25fcmV2aXNpb24YCCABKAQSLgoKZXhwaXJlc19hdBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASGQoMd29ya3NwYWNlX2lkGAogASgJSAGIAQESFwoKcHJvamVjdF9pZBgLIAEoCUgCiAEBQhQKEl9wYXJlbnRfc2Vzc2lvbl9pZEIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkInoKGldvcmtDb250ZXh0UmV2aXNpb25TdWJqZWN0Eh4KDHByaW5jaXBhbF9pZBgBIAEoCUIIukgFcgOwAQESPAoGc2NvcGVzGAIgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgi6SAWSAQIQQCLUAgohQ2hlY2tBdXRob3JpemF0aW9uUmV2aXNpb25SZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESJAoSb3duZXJfcHJpbmNpcGFsX2lkGAIgASgJQgi6SAVyA7ABARInChZhdXRob3JpemF0aW9uX3JldmlzaW9uGAMgASgEQge6SAQyAiAAEkoKCHN1YmplY3RzGAQgAygLMiwuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJldmlzaW9uU3ViamVjdEIKukgHkgEECAEQERItChRvcGVyYXRpb25fYmluZGluZ19pZBgFIAEoCUIKukgHcgUQARiABEgAiAEBEh0KEHNlYWxzX25vX2JpbmRpbmcYBiABKAhIAYgBAUIXChVfb3BlcmF0aW9uX2JpbmRpbmdfaWRCEwoRX3NlYWxzX25vX2JpbmRpbmcigwIKHEF1dGhvcml6ZUV2aWRlbmNlUmVhZFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIlChNjYWxsZXJfcHJpbmNpcGFsX2lkGAIgASgJQgi6SAVyA7ABARIpChJvd25lcl9wcmluY2lwYWxfaWQYAyABKAlCCLpIBXIDsAEBSACIAQESIAoHdGFza19pZBgEIAEoCUIKukgHcgUQARiABEgBiAEBEiMKCnNlc3Npb25faWQYBSABKAlCCrpIB3IFEAEYgARIAogBAUIVChNfb3duZXJfcHJpbmNpcGFsX2lkQgoKCF90YXNrX2lkQg0KC19zZXNzaW9uX2lkIpYBCiJDb25zdW1lU2luZ2xlVXNlV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHgoKY29udGV4dF9pZBgCIAEoCUIKukgHcgUQARiABBI2CgpleHBpcmVzX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEIGukgDyAEBKpsBChdXb3JrQ29udGV4dFJlcGxheVBvbGljeRIqCiZXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9VTlNQRUNJRklFRBAAEikKJVdPUktfQ09OVEVYVF9SRVBMQVlfUE9MSUNZX0lERU1QT1RFTlQQARIpCiVXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9TSU5HTEVfVVNFEAIy+wwKEldvcmtDb250ZXh0U2VydmljZRKDAQoaQ2hlY2tBdXRob3JpemF0aW9uUmV2aXNpb24SMy5zYWFzLmFjY291bnRzLnYxLkNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIYwvMYFAgDEAEwAToCEAFAAUgHUANYA2ABEnkKFUF1dGhvcml6ZUV2aWRlbmNlUmVhZBIuLnNhYXMuYWNjb3VudHMudjEuQXV0aG9yaXplRXZpZGVuY2VSZWFkUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIYwvMYFAgDEAEwAToCEAFAAUgHUANYA2ABEnoKEENvbnN1bWVTaW5nbGVVc2USNC5zYWFzLmFjY291bnRzLnYxLkNvbnN1bWVTaW5nbGVVc2VXb3JrQ29udGV4dFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARLKAQoJU3RhcnRUYXNrEi0uc2Fhcy5hY2NvdW50cy52MS5TdGFydFRhc2tXb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0ImnC8xhECAIQAyoMCgZvcmdfaWQQAhgBMAE6Igoec2Fhcy53b3JrX2NvbnRleHQudGFza19zdGFydGVkEAJAAUgFUANYBGABeAKC0+STAhs6ASoiFi92MS93b3JrLWNvbnRleHRzOnRhc2sShgEKFVN0YXJ0SW5zdGFsbGF0aW9uVGFzaxIuLnNhYXMuYWNjb3VudHMudjEuU3RhcnRJbnN0YWxsYXRpb25UYXNrUmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiGMLzGBQIAxABMAE6AhABQAFIB1ADWARgARLoAQoQU3RhcnRSb290U2Vzc2lvbhI0LnNhYXMuYWNjb3VudHMudjEuU3RhcnRSb290U2Vzc2lvbldvcmtDb250ZXh0UmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiecLzGEwIAhADKgwKBm9yZ19pZBACGAEwAToqCiZzYWFzLndvcmtfY29udGV4dC5yb290X3Nlc3Npb25fc3RhcnRlZBACQAFIBVAEWARgAXgCgtPkkwIjOgEqIh4vdjEvd29yay1jb250ZXh0czpyb290LXNlc3Npb24S6wEKEEV4Y2hhbmdlQXVkaWVuY2USNC5zYWFzLmFjY291bnRzLnYxLkV4Y2hhbmdlV29ya0NvbnRleHRBdWRpZW5jZVJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InzC8xhKCAIQAyoMCgZvcmdfaWQQAhgBMAE6KAokc2Fhcy53b3JrX2NvbnRleHQuYXVkaWVuY2VfZXhjaGFuZ2VkEAJAAUgFUARYBGABeAKC0+STAig6ASoiIy92MS93b3JrLWNvbnRleHRzOmV4Y2hhbmdlLWF1ZGllbmNlEuwBChFTdGFydENoaWxkU2Vzc2lvbhI1LnNhYXMuYWNjb3VudHMudjEuU3RhcnRDaGlsZFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InvC8xhNCAIQAyoMCgZvcmdfaWQQAhgBMAE6Kwonc2Fhcy53b3JrX2NvbnRleHQuY2hpbGRfc2Vzc2lvbl9zdGFydGVkEAJAAUgFUARYBGABeAKC0+STAiQ6ASoiHy92MS93b3JrLWNvbnRleHRzOmNoaWxkLXNlc3Npb24SyQEKEFJlbmV3V29ya0NvbnRleHQSKS5zYWFzLmFjY291bnRzLnYxLlJlbmV3V29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJlwvMYPwgCEAMqDAoGb3JnX2lkEAIYATABOh0KGXNhYXMud29ya19jb250ZXh0LnJlbmV3ZWQQAkABSAVQBFgEYAF4AoLT5JMCHDoBKiIXL3YxL3dvcmstY29udGV4dHM6cmVuZXdiBnByb3RvMw", [file_buf_validate_validate, file_google_api_annotations, file_google_protobuf_empty, file_google_protobuf_timestamp, file_saas_policy_v1_options]); + fileDesc("CiRzYWFzL2FjY291bnRzL3YxL3dvcmtfY29udGV4dHMucHJvdG8SEHNhYXMuYWNjb3VudHMudjEiiQEKEFdvcmtDb250ZXh0U2NvcGUSIQoNcmVzb3VyY2Vfa2luZBgBIAEoCUIKukgHcgUQARiAARImCgdhY3Rpb25zGAIgAygJQhW6SBKSAQ8IARBAGAEiB3IFEAEYgAESKgoMcmVzb3VyY2VfaWRzGAMgAygJQhS6SBGSAQ4QgAIYASIHcgUQARiABCLrAwobU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHAoHdGFza19pZBgCIAEoCUILukgI2AEBcgOwAQESGgoSYWN0b3JfcHJpbmNpcGFsX2lkGAQgASgJEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBEi8KEm9wZXJhdGlvbl9iaW5kaW5ncxgLIAMoCUITukgQkgENEEAYASIHcgUQARiAAkIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkSgQIAxAEUgpzZXNzaW9uX2lkIr8DChxTdGFydEluc3RhbGxhdGlvblRhc2tSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESIQoPaW5zdGFsbGF0aW9uX2lkGAIgASgJQgi6SAVyA7ABARIZCgd0YXNrX2lkGAMgASgJQgi6SAVyA7ABARJIChBhdXRob3JpdHlfc2NvcGVzGAUgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEhwKCGF1ZGllbmNlGAYgASgJQgq6SAdyBRABGIAEEkAKDXJlcGxheV9wb2xpY3kYByABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAggASgFQgq6SAcaBRiEBygAEiUKDHdvcmtzcGFjZV9pZBgJIAEoCUIKukgHcgUQARiABEgAiAEBEiMKCnByb2plY3RfaWQYCiABKAlCCrpIB3IFEAEYgARIAYgBAUIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkSgQIBBAFUgpzZXNzaW9uX2lkIo0CCiJTdGFydFJvb3RTZXNzaW9uV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESLgoZcGFyZW50X3dvcmtfY29udGV4dF90b2tlbhgCIAEoCUILukgIcgYQARiAgAISHAoKc2Vzc2lvbl9pZBgDIAEoCUIIukgFcgOwAQESHAoIYXVkaWVuY2UYBCABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgFIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYBiABKAVCCrpIBxoFGIQHKAAiugIKIkV4Y2hhbmdlV29ya0NvbnRleHRBdWRpZW5jZVJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIcCghhdWRpZW5jZRgDIAEoCUIKukgHcgUQARiABBJJChFhdHRlbnVhdGVkX3Njb3BlcxgEIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIKukgHkgEECAEQQBJACg1yZXBsYXlfcG9saWN5GAUgASgOMikuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJlcGxheVBvbGljeRIfCgt0dGxfc2Vjb25kcxgGIAEoBUIKukgHGgUYhAcoACLwAgojU3RhcnRDaGlsZFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIkChJhY3Rvcl9wcmluY2lwYWxfaWQYBCABKAlCCLpIBXIDsAEBEkYKDmdyYW50ZWRfc2NvcGVzGAUgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEhwKCGF1ZGllbmNlGAYgASgJQgq6SAdyBRABGIAEEkAKDXJlcGxheV9wb2xpY3kYByABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAggASgFQgq6SAcaBRiEBygASgQIAxAEUgpzZXNzaW9uX2lkIr8CChdSZW5ld1dvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEiEKCGF1ZGllbmNlGAMgASgJQgq6SAdyBRABGIAESACIAQESRwoRYXR0ZW51YXRlZF9zY29wZXMYBCADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCLpIBZIBAhBAEkAKDXJlcGxheV9wb2xpY3kYBSABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAYgASgFQgq6SAcaBRiEBygAQgsKCV9hdWRpZW5jZSLxAgoRSXNzdWVkV29ya0NvbnRleHQSDQoFdG9rZW4YASABKAkSDgoGb3JnX2lkGAIgASgJEhoKEm93bmVyX3ByaW5jaXBhbF9pZBgDIAEoCRIPCgd0YXNrX2lkGAQgASgJEhIKCnNlc3Npb25faWQYBSABKAkSHgoRcGFyZW50X3Nlc3Npb25faWQYBiABKAlIAIgBARIiChpjdXJyZW50X2FjdG9yX3ByaW5jaXBhbF9pZBgHIAEoCRIeChZhdXRob3JpemF0aW9uX3JldmlzaW9uGAggASgEEi4KCmV4cGlyZXNfYXQYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhkKDHdvcmtzcGFjZV9pZBgKIAEoCUgBiAEBEhcKCnByb2plY3RfaWQYCyABKAlIAogBAUIUChJfcGFyZW50X3Nlc3Npb25faWRCDwoNX3dvcmtzcGFjZV9pZEINCgtfcHJvamVjdF9pZCJ6ChpXb3JrQ29udGV4dFJldmlzaW9uU3ViamVjdBIeCgxwcmluY2lwYWxfaWQYASABKAlCCLpIBXIDsAEBEjwKBnNjb3BlcxgCIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIIukgFkgECEEAi1AIKIUNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uUmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEiQKEm93bmVyX3ByaW5jaXBhbF9pZBgCIAEoCUIIukgFcgOwAQESJwoWYXV0aG9yaXphdGlvbl9yZXZpc2lvbhgDIAEoBEIHukgEMgIgABJKCghzdWJqZWN0cxgEIAMoCzIsLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXZpc2lvblN1YmplY3RCCrpIB5IBBAgBEBESLQoUb3BlcmF0aW9uX2JpbmRpbmdfaWQYBSABKAlCCrpIB3IFEAEYgARIAIgBARIdChBzZWFsc19ub19iaW5kaW5nGAYgASgISAGIAQFCFwoVX29wZXJhdGlvbl9iaW5kaW5nX2lkQhMKEV9zZWFsc19ub19iaW5kaW5nIoMCChxBdXRob3JpemVFdmlkZW5jZVJlYWRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESJQoTY2FsbGVyX3ByaW5jaXBhbF9pZBgCIAEoCUIIukgFcgOwAQESKQoSb3duZXJfcHJpbmNpcGFsX2lkGAMgASgJQgi6SAVyA7ABAUgAiAEBEiAKB3Rhc2tfaWQYBCABKAlCCrpIB3IFEAEYgARIAYgBARIjCgpzZXNzaW9uX2lkGAUgASgJQgq6SAdyBRABGIAESAKIAQFCFQoTX293bmVyX3ByaW5jaXBhbF9pZEIKCghfdGFza19pZEINCgtfc2Vzc2lvbl9pZCKWAQoiQ29uc3VtZVNpbmdsZVVzZVdvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEh4KCmNvbnRleHRfaWQYAiABKAlCCrpIB3IFEAEYgAQSNgoKZXhwaXJlc19hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASqbAQoXV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSKgomV09SS19DT05URVhUX1JFUExBWV9QT0xJQ1lfVU5TUEVDSUZJRUQQABIpCiVXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9JREVNUE9URU5UEAESKQolV09SS19DT05URVhUX1JFUExBWV9QT0xJQ1lfU0lOR0xFX1VTRRACMvsMChJXb3JrQ29udGV4dFNlcnZpY2USgwEKGkNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uEjMuc2Fhcy5hY2NvdW50cy52MS5DaGVja0F1dGhvcml6YXRpb25SZXZpc2lvblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARJ5ChVBdXRob3JpemVFdmlkZW5jZVJlYWQSLi5zYWFzLmFjY291bnRzLnYxLkF1dGhvcml6ZUV2aWRlbmNlUmVhZFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARJ6ChBDb25zdW1lU2luZ2xlVXNlEjQuc2Fhcy5hY2NvdW50cy52MS5Db25zdW1lU2luZ2xlVXNlV29ya0NvbnRleHRSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IhjC8xgUCAMQATABOgIQAUABSAdQA1gDYAESygEKCVN0YXJ0VGFzaxItLnNhYXMuYWNjb3VudHMudjEuU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJpwvMYRAgCEAMqDAoGb3JnX2lkEAIYATABOiIKHnNhYXMud29ya19jb250ZXh0LnRhc2tfc3RhcnRlZBACQAFIBVADWARgAXgCgtPkkwIbOgEqIhYvdjEvd29yay1jb250ZXh0czp0YXNrEoYBChVTdGFydEluc3RhbGxhdGlvblRhc2sSLi5zYWFzLmFjY291bnRzLnYxLlN0YXJ0SW5zdGFsbGF0aW9uVGFza1JlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0IhjC8xgUCAMQATABOgIQAUABSAdQA1gEYAES6AEKEFN0YXJ0Um9vdFNlc3Npb24SNC5zYWFzLmFjY291bnRzLnYxLlN0YXJ0Um9vdFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InnC8xhMCAIQAyoMCgZvcmdfaWQQAhgBMAE6Kgomc2Fhcy53b3JrX2NvbnRleHQucm9vdF9zZXNzaW9uX3N0YXJ0ZWQQAkABSAVQBFgEYAF4AoLT5JMCIzoBKiIeL3YxL3dvcmstY29udGV4dHM6cm9vdC1zZXNzaW9uEusBChBFeGNoYW5nZUF1ZGllbmNlEjQuc2Fhcy5hY2NvdW50cy52MS5FeGNoYW5nZVdvcmtDb250ZXh0QXVkaWVuY2VSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJ8wvMYSggCEAMqDAoGb3JnX2lkEAIYATABOigKJHNhYXMud29ya19jb250ZXh0LmF1ZGllbmNlX2V4Y2hhbmdlZBACQAFIBVAEWARgAXgCgtPkkwIoOgEqIiMvdjEvd29yay1jb250ZXh0czpleGNoYW5nZS1hdWRpZW5jZRLsAQoRU3RhcnRDaGlsZFNlc3Npb24SNS5zYWFzLmFjY291bnRzLnYxLlN0YXJ0Q2hpbGRTZXNzaW9uV29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJ7wvMYTQgCEAMqDAoGb3JnX2lkEAIYATABOisKJ3NhYXMud29ya19jb250ZXh0LmNoaWxkX3Nlc3Npb25fc3RhcnRlZBACQAFIBVAEWARgAXgCgtPkkwIkOgEqIh8vdjEvd29yay1jb250ZXh0czpjaGlsZC1zZXNzaW9uEskBChBSZW5ld1dvcmtDb250ZXh0Eikuc2Fhcy5hY2NvdW50cy52MS5SZW5ld1dvcmtDb250ZXh0UmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiZcLzGD8IAhADKgwKBm9yZ19pZBACGAEwATodChlzYWFzLndvcmtfY29udGV4dC5yZW5ld2VkEAJAAUgFUARYBGABeAKC0+STAhw6ASoiFy92MS93b3JrLWNvbnRleHRzOnJlbmV3YgZwcm90bzM", [file_buf_validate_validate, file_google_api_annotations, file_google_protobuf_empty, file_google_protobuf_timestamp, file_saas_policy_v1_options]); /** * WorkContextScope is one product-neutral authority slice. Product plugins @@ -123,6 +123,18 @@ export type StartTaskWorkContextRequest = Message<"saas.accounts.v1.StartTaskWor * @generated from field: optional string project_id = 10; */ projectId?: string; + + /** + * Operation bindings of the audience module, by name, whose invoke scopes + * this capability carries beside authority_scopes. The host resolves each + * name to the binding as installed at org_id, narrowed by that installation + * exactly as the module's delegated exchange redeems it, and keeps each + * resource only if the person holds it. The caller names a binding and never + * its resource ids. A direct human-owned mint only. + * + * @generated from field: repeated string operation_bindings = 11; + */ + operationBindings: string[]; }; /** diff --git a/module/services/frontend/code/src/gen/saas/accounts/v1/work_contexts_pb.ts b/module/services/frontend/code/src/gen/saas/accounts/v1/work_contexts_pb.ts index 1ae3625b3..83a0d4391 100644 --- a/module/services/frontend/code/src/gen/saas/accounts/v1/work_contexts_pb.ts +++ b/module/services/frontend/code/src/gen/saas/accounts/v1/work_contexts_pb.ts @@ -15,7 +15,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file saas/accounts/v1/work_contexts.proto. */ export const file_saas_accounts_v1_work_contexts: GenFile = /*@__PURE__*/ - fileDesc("CiRzYWFzL2FjY291bnRzL3YxL3dvcmtfY29udGV4dHMucHJvdG8SEHNhYXMuYWNjb3VudHMudjEiiQEKEFdvcmtDb250ZXh0U2NvcGUSIQoNcmVzb3VyY2Vfa2luZBgBIAEoCUIKukgHcgUQARiAARImCgdhY3Rpb25zGAIgAygJQhW6SBKSAQ8IARBAGAEiB3IFEAEYgAESKgoMcmVzb3VyY2VfaWRzGAMgAygJQhS6SBGSAQ4QgAIYASIHcgUQARiABCK6AwobU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHAoHdGFza19pZBgCIAEoCUILukgI2AEBcgOwAQESGgoSYWN0b3JfcHJpbmNpcGFsX2lkGAQgASgJEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBQg8KDV93b3Jrc3BhY2VfaWRCDQoLX3Byb2plY3RfaWRKBAgDEARSCnNlc3Npb25faWQivwMKHFN0YXJ0SW5zdGFsbGF0aW9uVGFza1JlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIhCg9pbnN0YWxsYXRpb25faWQYAiABKAlCCLpIBXIDsAEBEhkKB3Rhc2tfaWQYAyABKAlCCLpIBXIDsAEBEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBQg8KDV93b3Jrc3BhY2VfaWRCDQoLX3Byb2plY3RfaWRKBAgEEAVSCnNlc3Npb25faWQijQIKIlN0YXJ0Um9vdFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIcCgpzZXNzaW9uX2lkGAMgASgJQgi6SAVyA7ABARIcCghhdWRpZW5jZRgEIAEoCUIKukgHcgUQARiABBJACg1yZXBsYXlfcG9saWN5GAUgASgOMikuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJlcGxheVBvbGljeRIfCgt0dGxfc2Vjb25kcxgGIAEoBUIKukgHGgUYhAcoACK6AgoiRXhjaGFuZ2VXb3JrQ29udGV4dEF1ZGllbmNlUmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEhwKCGF1ZGllbmNlGAMgASgJQgq6SAdyBRABGIAEEkkKEWF0dGVudWF0ZWRfc2NvcGVzGAQgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEkAKDXJlcGxheV9wb2xpY3kYBSABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAYgASgFQgq6SAcaBRiEBygAIvACCiNTdGFydENoaWxkU2Vzc2lvbldvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEiQKEmFjdG9yX3ByaW5jaXBhbF9pZBgEIAEoCUIIukgFcgOwAQESRgoOZ3JhbnRlZF9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKABKBAgDEARSCnNlc3Npb25faWQivwIKF1JlbmV3V29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESLgoZcGFyZW50X3dvcmtfY29udGV4dF90b2tlbhgCIAEoCUILukgIcgYQARiAgAISIQoIYXVkaWVuY2UYAyABKAlCCrpIB3IFEAEYgARIAIgBARJHChFhdHRlbnVhdGVkX3Njb3BlcxgEIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIIukgFkgECEEASQAoNcmVwbGF5X3BvbGljeRgFIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYBiABKAVCCrpIBxoFGIQHKABCCwoJX2F1ZGllbmNlIvECChFJc3N1ZWRXb3JrQ29udGV4dBINCgV0b2tlbhgBIAEoCRIOCgZvcmdfaWQYAiABKAkSGgoSb3duZXJfcHJpbmNpcGFsX2lkGAMgASgJEg8KB3Rhc2tfaWQYBCABKAkSEgoKc2Vzc2lvbl9pZBgFIAEoCRIeChFwYXJlbnRfc2Vzc2lvbl9pZBgGIAEoCUgAiAEBEiIKGmN1cnJlbnRfYWN0b3JfcHJpbmNpcGFsX2lkGAcgASgJEh4KFmF1dGhvcml6YXRpb25fcmV2aXNpb24YCCABKAQSLgoKZXhwaXJlc19hdBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASGQoMd29ya3NwYWNlX2lkGAogASgJSAGIAQESFwoKcHJvamVjdF9pZBgLIAEoCUgCiAEBQhQKEl9wYXJlbnRfc2Vzc2lvbl9pZEIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkInoKGldvcmtDb250ZXh0UmV2aXNpb25TdWJqZWN0Eh4KDHByaW5jaXBhbF9pZBgBIAEoCUIIukgFcgOwAQESPAoGc2NvcGVzGAIgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgi6SAWSAQIQQCLUAgohQ2hlY2tBdXRob3JpemF0aW9uUmV2aXNpb25SZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESJAoSb3duZXJfcHJpbmNpcGFsX2lkGAIgASgJQgi6SAVyA7ABARInChZhdXRob3JpemF0aW9uX3JldmlzaW9uGAMgASgEQge6SAQyAiAAEkoKCHN1YmplY3RzGAQgAygLMiwuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJldmlzaW9uU3ViamVjdEIKukgHkgEECAEQERItChRvcGVyYXRpb25fYmluZGluZ19pZBgFIAEoCUIKukgHcgUQARiABEgAiAEBEh0KEHNlYWxzX25vX2JpbmRpbmcYBiABKAhIAYgBAUIXChVfb3BlcmF0aW9uX2JpbmRpbmdfaWRCEwoRX3NlYWxzX25vX2JpbmRpbmcigwIKHEF1dGhvcml6ZUV2aWRlbmNlUmVhZFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIlChNjYWxsZXJfcHJpbmNpcGFsX2lkGAIgASgJQgi6SAVyA7ABARIpChJvd25lcl9wcmluY2lwYWxfaWQYAyABKAlCCLpIBXIDsAEBSACIAQESIAoHdGFza19pZBgEIAEoCUIKukgHcgUQARiABEgBiAEBEiMKCnNlc3Npb25faWQYBSABKAlCCrpIB3IFEAEYgARIAogBAUIVChNfb3duZXJfcHJpbmNpcGFsX2lkQgoKCF90YXNrX2lkQg0KC19zZXNzaW9uX2lkIpYBCiJDb25zdW1lU2luZ2xlVXNlV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHgoKY29udGV4dF9pZBgCIAEoCUIKukgHcgUQARiABBI2CgpleHBpcmVzX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEIGukgDyAEBKpsBChdXb3JrQ29udGV4dFJlcGxheVBvbGljeRIqCiZXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9VTlNQRUNJRklFRBAAEikKJVdPUktfQ09OVEVYVF9SRVBMQVlfUE9MSUNZX0lERU1QT1RFTlQQARIpCiVXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9TSU5HTEVfVVNFEAIy+wwKEldvcmtDb250ZXh0U2VydmljZRKDAQoaQ2hlY2tBdXRob3JpemF0aW9uUmV2aXNpb24SMy5zYWFzLmFjY291bnRzLnYxLkNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIYwvMYFAgDEAEwAToCEAFAAUgHUANYA2ABEnkKFUF1dGhvcml6ZUV2aWRlbmNlUmVhZBIuLnNhYXMuYWNjb3VudHMudjEuQXV0aG9yaXplRXZpZGVuY2VSZWFkUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIYwvMYFAgDEAEwAToCEAFAAUgHUANYA2ABEnoKEENvbnN1bWVTaW5nbGVVc2USNC5zYWFzLmFjY291bnRzLnYxLkNvbnN1bWVTaW5nbGVVc2VXb3JrQ29udGV4dFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARLKAQoJU3RhcnRUYXNrEi0uc2Fhcy5hY2NvdW50cy52MS5TdGFydFRhc2tXb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0ImnC8xhECAIQAyoMCgZvcmdfaWQQAhgBMAE6Igoec2Fhcy53b3JrX2NvbnRleHQudGFza19zdGFydGVkEAJAAUgFUANYBGABeAKC0+STAhs6ASoiFi92MS93b3JrLWNvbnRleHRzOnRhc2sShgEKFVN0YXJ0SW5zdGFsbGF0aW9uVGFzaxIuLnNhYXMuYWNjb3VudHMudjEuU3RhcnRJbnN0YWxsYXRpb25UYXNrUmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiGMLzGBQIAxABMAE6AhABQAFIB1ADWARgARLoAQoQU3RhcnRSb290U2Vzc2lvbhI0LnNhYXMuYWNjb3VudHMudjEuU3RhcnRSb290U2Vzc2lvbldvcmtDb250ZXh0UmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiecLzGEwIAhADKgwKBm9yZ19pZBACGAEwAToqCiZzYWFzLndvcmtfY29udGV4dC5yb290X3Nlc3Npb25fc3RhcnRlZBACQAFIBVAEWARgAXgCgtPkkwIjOgEqIh4vdjEvd29yay1jb250ZXh0czpyb290LXNlc3Npb24S6wEKEEV4Y2hhbmdlQXVkaWVuY2USNC5zYWFzLmFjY291bnRzLnYxLkV4Y2hhbmdlV29ya0NvbnRleHRBdWRpZW5jZVJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InzC8xhKCAIQAyoMCgZvcmdfaWQQAhgBMAE6KAokc2Fhcy53b3JrX2NvbnRleHQuYXVkaWVuY2VfZXhjaGFuZ2VkEAJAAUgFUARYBGABeAKC0+STAig6ASoiIy92MS93b3JrLWNvbnRleHRzOmV4Y2hhbmdlLWF1ZGllbmNlEuwBChFTdGFydENoaWxkU2Vzc2lvbhI1LnNhYXMuYWNjb3VudHMudjEuU3RhcnRDaGlsZFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InvC8xhNCAIQAyoMCgZvcmdfaWQQAhgBMAE6Kwonc2Fhcy53b3JrX2NvbnRleHQuY2hpbGRfc2Vzc2lvbl9zdGFydGVkEAJAAUgFUARYBGABeAKC0+STAiQ6ASoiHy92MS93b3JrLWNvbnRleHRzOmNoaWxkLXNlc3Npb24SyQEKEFJlbmV3V29ya0NvbnRleHQSKS5zYWFzLmFjY291bnRzLnYxLlJlbmV3V29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJlwvMYPwgCEAMqDAoGb3JnX2lkEAIYATABOh0KGXNhYXMud29ya19jb250ZXh0LnJlbmV3ZWQQAkABSAVQBFgEYAF4AoLT5JMCHDoBKiIXL3YxL3dvcmstY29udGV4dHM6cmVuZXdCuQEKFGNvbS5zYWFzLmFjY291bnRzLnYxQhFXb3JrQ29udGV4dHNQcm90b1ABWixhY2NvdW50cy9wa2cvZ2VuL3NhYXMvYWNjb3VudHMvdjE7YWNjb3VudHN2MaICA1NBWKoCEFNhYXMuQWNjb3VudHMuVjHKAhBTYWFzXEFjY291bnRzXFYx4gIcU2Fhc1xBY2NvdW50c1xWMVxHUEJNZXRhZGF0YeoCElNhYXM6OkFjY291bnRzOjpWMWIGcHJvdG8z", [file_buf_validate_validate, file_google_api_annotations, file_google_protobuf_empty, file_google_protobuf_timestamp, file_saas_policy_v1_options]); + fileDesc("CiRzYWFzL2FjY291bnRzL3YxL3dvcmtfY29udGV4dHMucHJvdG8SEHNhYXMuYWNjb3VudHMudjEiiQEKEFdvcmtDb250ZXh0U2NvcGUSIQoNcmVzb3VyY2Vfa2luZBgBIAEoCUIKukgHcgUQARiAARImCgdhY3Rpb25zGAIgAygJQhW6SBKSAQ8IARBAGAEiB3IFEAEYgAESKgoMcmVzb3VyY2VfaWRzGAMgAygJQhS6SBGSAQ4QgAIYASIHcgUQARiABCLrAwobU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESHAoHdGFza19pZBgCIAEoCUILukgI2AEBcgOwAQESGgoSYWN0b3JfcHJpbmNpcGFsX2lkGAQgASgJEkgKEGF1dGhvcml0eV9zY29wZXMYBSADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCrpIB5IBBAgBEEASHAoIYXVkaWVuY2UYBiABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgHIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYCCABKAVCCrpIBxoFGIQHKAASJQoMd29ya3NwYWNlX2lkGAkgASgJQgq6SAdyBRABGIAESACIAQESIwoKcHJvamVjdF9pZBgKIAEoCUIKukgHcgUQARiABEgBiAEBEi8KEm9wZXJhdGlvbl9iaW5kaW5ncxgLIAMoCUITukgQkgENEEAYASIHcgUQARiAAkIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkSgQIAxAEUgpzZXNzaW9uX2lkIr8DChxTdGFydEluc3RhbGxhdGlvblRhc2tSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESIQoPaW5zdGFsbGF0aW9uX2lkGAIgASgJQgi6SAVyA7ABARIZCgd0YXNrX2lkGAMgASgJQgi6SAVyA7ABARJIChBhdXRob3JpdHlfc2NvcGVzGAUgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEhwKCGF1ZGllbmNlGAYgASgJQgq6SAdyBRABGIAEEkAKDXJlcGxheV9wb2xpY3kYByABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAggASgFQgq6SAcaBRiEBygAEiUKDHdvcmtzcGFjZV9pZBgJIAEoCUIKukgHcgUQARiABEgAiAEBEiMKCnByb2plY3RfaWQYCiABKAlCCrpIB3IFEAEYgARIAYgBAUIPCg1fd29ya3NwYWNlX2lkQg0KC19wcm9qZWN0X2lkSgQIBBAFUgpzZXNzaW9uX2lkIo0CCiJTdGFydFJvb3RTZXNzaW9uV29ya0NvbnRleHRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESLgoZcGFyZW50X3dvcmtfY29udGV4dF90b2tlbhgCIAEoCUILukgIcgYQARiAgAISHAoKc2Vzc2lvbl9pZBgDIAEoCUIIukgFcgOwAQESHAoIYXVkaWVuY2UYBCABKAlCCrpIB3IFEAEYgAQSQAoNcmVwbGF5X3BvbGljeRgFIAEoDjIpLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSHwoLdHRsX3NlY29uZHMYBiABKAVCCrpIBxoFGIQHKAAiugIKIkV4Y2hhbmdlV29ya0NvbnRleHRBdWRpZW5jZVJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIcCghhdWRpZW5jZRgDIAEoCUIKukgHcgUQARiABBJJChFhdHRlbnVhdGVkX3Njb3BlcxgEIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIKukgHkgEECAEQQBJACg1yZXBsYXlfcG9saWN5GAUgASgOMikuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFJlcGxheVBvbGljeRIfCgt0dGxfc2Vjb25kcxgGIAEoBUIKukgHGgUYhAcoACLwAgojU3RhcnRDaGlsZFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QSGAoGb3JnX2lkGAEgASgJQgi6SAVyA7ABARIuChlwYXJlbnRfd29ya19jb250ZXh0X3Rva2VuGAIgASgJQgu6SAhyBhABGICAAhIkChJhY3Rvcl9wcmluY2lwYWxfaWQYBCABKAlCCLpIBXIDsAEBEkYKDmdyYW50ZWRfc2NvcGVzGAUgAygLMiIuc2Fhcy5hY2NvdW50cy52MS5Xb3JrQ29udGV4dFNjb3BlQgq6SAeSAQQIARBAEhwKCGF1ZGllbmNlGAYgASgJQgq6SAdyBRABGIAEEkAKDXJlcGxheV9wb2xpY3kYByABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAggASgFQgq6SAcaBRiEBygASgQIAxAEUgpzZXNzaW9uX2lkIr8CChdSZW5ld1dvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEi4KGXBhcmVudF93b3JrX2NvbnRleHRfdG9rZW4YAiABKAlCC7pICHIGEAEYgIACEiEKCGF1ZGllbmNlGAMgASgJQgq6SAdyBRABGIAESACIAQESRwoRYXR0ZW51YXRlZF9zY29wZXMYBCADKAsyIi5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0U2NvcGVCCLpIBZIBAhBAEkAKDXJlcGxheV9wb2xpY3kYBSABKA4yKS5zYWFzLmFjY291bnRzLnYxLldvcmtDb250ZXh0UmVwbGF5UG9saWN5Eh8KC3R0bF9zZWNvbmRzGAYgASgFQgq6SAcaBRiEBygAQgsKCV9hdWRpZW5jZSLxAgoRSXNzdWVkV29ya0NvbnRleHQSDQoFdG9rZW4YASABKAkSDgoGb3JnX2lkGAIgASgJEhoKEm93bmVyX3ByaW5jaXBhbF9pZBgDIAEoCRIPCgd0YXNrX2lkGAQgASgJEhIKCnNlc3Npb25faWQYBSABKAkSHgoRcGFyZW50X3Nlc3Npb25faWQYBiABKAlIAIgBARIiChpjdXJyZW50X2FjdG9yX3ByaW5jaXBhbF9pZBgHIAEoCRIeChZhdXRob3JpemF0aW9uX3JldmlzaW9uGAggASgEEi4KCmV4cGlyZXNfYXQYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhkKDHdvcmtzcGFjZV9pZBgKIAEoCUgBiAEBEhcKCnByb2plY3RfaWQYCyABKAlIAogBAUIUChJfcGFyZW50X3Nlc3Npb25faWRCDwoNX3dvcmtzcGFjZV9pZEINCgtfcHJvamVjdF9pZCJ6ChpXb3JrQ29udGV4dFJldmlzaW9uU3ViamVjdBIeCgxwcmluY2lwYWxfaWQYASABKAlCCLpIBXIDsAEBEjwKBnNjb3BlcxgCIAMoCzIiLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRTY29wZUIIukgFkgECEEAi1AIKIUNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uUmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEiQKEm93bmVyX3ByaW5jaXBhbF9pZBgCIAEoCUIIukgFcgOwAQESJwoWYXV0aG9yaXphdGlvbl9yZXZpc2lvbhgDIAEoBEIHukgEMgIgABJKCghzdWJqZWN0cxgEIAMoCzIsLnNhYXMuYWNjb3VudHMudjEuV29ya0NvbnRleHRSZXZpc2lvblN1YmplY3RCCrpIB5IBBAgBEBESLQoUb3BlcmF0aW9uX2JpbmRpbmdfaWQYBSABKAlCCrpIB3IFEAEYgARIAIgBARIdChBzZWFsc19ub19iaW5kaW5nGAYgASgISAGIAQFCFwoVX29wZXJhdGlvbl9iaW5kaW5nX2lkQhMKEV9zZWFsc19ub19iaW5kaW5nIoMCChxBdXRob3JpemVFdmlkZW5jZVJlYWRSZXF1ZXN0EhgKBm9yZ19pZBgBIAEoCUIIukgFcgOwAQESJQoTY2FsbGVyX3ByaW5jaXBhbF9pZBgCIAEoCUIIukgFcgOwAQESKQoSb3duZXJfcHJpbmNpcGFsX2lkGAMgASgJQgi6SAVyA7ABAUgAiAEBEiAKB3Rhc2tfaWQYBCABKAlCCrpIB3IFEAEYgARIAYgBARIjCgpzZXNzaW9uX2lkGAUgASgJQgq6SAdyBRABGIAESAKIAQFCFQoTX293bmVyX3ByaW5jaXBhbF9pZEIKCghfdGFza19pZEINCgtfc2Vzc2lvbl9pZCKWAQoiQ29uc3VtZVNpbmdsZVVzZVdvcmtDb250ZXh0UmVxdWVzdBIYCgZvcmdfaWQYASABKAlCCLpIBXIDsAEBEh4KCmNvbnRleHRfaWQYAiABKAlCCrpIB3IFEAEYgAQSNgoKZXhwaXJlc19hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCBrpIA8gBASqbAQoXV29ya0NvbnRleHRSZXBsYXlQb2xpY3kSKgomV09SS19DT05URVhUX1JFUExBWV9QT0xJQ1lfVU5TUEVDSUZJRUQQABIpCiVXT1JLX0NPTlRFWFRfUkVQTEFZX1BPTElDWV9JREVNUE9URU5UEAESKQolV09SS19DT05URVhUX1JFUExBWV9QT0xJQ1lfU0lOR0xFX1VTRRACMvsMChJXb3JrQ29udGV4dFNlcnZpY2USgwEKGkNoZWNrQXV0aG9yaXphdGlvblJldmlzaW9uEjMuc2Fhcy5hY2NvdW50cy52MS5DaGVja0F1dGhvcml6YXRpb25SZXZpc2lvblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARJ5ChVBdXRob3JpemVFdmlkZW5jZVJlYWQSLi5zYWFzLmFjY291bnRzLnYxLkF1dGhvcml6ZUV2aWRlbmNlUmVhZFJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiGMLzGBQIAxABMAE6AhABQAFIB1ADWANgARJ6ChBDb25zdW1lU2luZ2xlVXNlEjQuc2Fhcy5hY2NvdW50cy52MS5Db25zdW1lU2luZ2xlVXNlV29ya0NvbnRleHRSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IhjC8xgUCAMQATABOgIQAUABSAdQA1gDYAESygEKCVN0YXJ0VGFzaxItLnNhYXMuYWNjb3VudHMudjEuU3RhcnRUYXNrV29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJpwvMYRAgCEAMqDAoGb3JnX2lkEAIYATABOiIKHnNhYXMud29ya19jb250ZXh0LnRhc2tfc3RhcnRlZBACQAFIBVADWARgAXgCgtPkkwIbOgEqIhYvdjEvd29yay1jb250ZXh0czp0YXNrEoYBChVTdGFydEluc3RhbGxhdGlvblRhc2sSLi5zYWFzLmFjY291bnRzLnYxLlN0YXJ0SW5zdGFsbGF0aW9uVGFza1JlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0IhjC8xgUCAMQATABOgIQAUABSAdQA1gEYAES6AEKEFN0YXJ0Um9vdFNlc3Npb24SNC5zYWFzLmFjY291bnRzLnYxLlN0YXJ0Um9vdFNlc3Npb25Xb3JrQ29udGV4dFJlcXVlc3QaIy5zYWFzLmFjY291bnRzLnYxLklzc3VlZFdvcmtDb250ZXh0InnC8xhMCAIQAyoMCgZvcmdfaWQQAhgBMAE6Kgomc2Fhcy53b3JrX2NvbnRleHQucm9vdF9zZXNzaW9uX3N0YXJ0ZWQQAkABSAVQBFgEYAF4AoLT5JMCIzoBKiIeL3YxL3dvcmstY29udGV4dHM6cm9vdC1zZXNzaW9uEusBChBFeGNoYW5nZUF1ZGllbmNlEjQuc2Fhcy5hY2NvdW50cy52MS5FeGNoYW5nZVdvcmtDb250ZXh0QXVkaWVuY2VSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJ8wvMYSggCEAMqDAoGb3JnX2lkEAIYATABOigKJHNhYXMud29ya19jb250ZXh0LmF1ZGllbmNlX2V4Y2hhbmdlZBACQAFIBVAEWARgAXgCgtPkkwIoOgEqIiMvdjEvd29yay1jb250ZXh0czpleGNoYW5nZS1hdWRpZW5jZRLsAQoRU3RhcnRDaGlsZFNlc3Npb24SNS5zYWFzLmFjY291bnRzLnYxLlN0YXJ0Q2hpbGRTZXNzaW9uV29ya0NvbnRleHRSZXF1ZXN0GiMuc2Fhcy5hY2NvdW50cy52MS5Jc3N1ZWRXb3JrQ29udGV4dCJ7wvMYTQgCEAMqDAoGb3JnX2lkEAIYATABOisKJ3NhYXMud29ya19jb250ZXh0LmNoaWxkX3Nlc3Npb25fc3RhcnRlZBACQAFIBVAEWARgAXgCgtPkkwIkOgEqIh8vdjEvd29yay1jb250ZXh0czpjaGlsZC1zZXNzaW9uEskBChBSZW5ld1dvcmtDb250ZXh0Eikuc2Fhcy5hY2NvdW50cy52MS5SZW5ld1dvcmtDb250ZXh0UmVxdWVzdBojLnNhYXMuYWNjb3VudHMudjEuSXNzdWVkV29ya0NvbnRleHQiZcLzGD8IAhADKgwKBm9yZ19pZBACGAEwATodChlzYWFzLndvcmtfY29udGV4dC5yZW5ld2VkEAJAAUgFUARYBGABeAKC0+STAhw6ASoiFy92MS93b3JrLWNvbnRleHRzOnJlbmV3QrkBChRjb20uc2Fhcy5hY2NvdW50cy52MUIRV29ya0NvbnRleHRzUHJvdG9QAVosYWNjb3VudHMvcGtnL2dlbi9zYWFzL2FjY291bnRzL3YxO2FjY291bnRzdjGiAgNTQViqAhBTYWFzLkFjY291bnRzLlYxygIQU2Fhc1xBY2NvdW50c1xWMeICHFNhYXNcQWNjb3VudHNcVjFcR1BCTWV0YWRhdGHqAhJTYWFzOjpBY2NvdW50czo6VjFiBnByb3RvMw", [file_buf_validate_validate, file_google_api_annotations, file_google_protobuf_empty, file_google_protobuf_timestamp, file_saas_policy_v1_options]); /** * WorkContextScope is one product-neutral authority slice. Product plugins @@ -123,6 +123,18 @@ export type StartTaskWorkContextRequest = Message<"saas.accounts.v1.StartTaskWor * @generated from field: optional string project_id = 10; */ projectId?: string; + + /** + * Operation bindings of the audience module, by name, whose invoke scopes + * this capability carries beside authority_scopes. The host resolves each + * name to the binding as installed at org_id, narrowed by that installation + * exactly as the module's delegated exchange redeems it, and keeps each + * resource only if the person holds it. The caller names a binding and never + * its resource ids. A direct human-owned mint only. + * + * @generated from field: repeated string operation_bindings = 11; + */ + operationBindings: string[]; }; /**