ankka 0.7.1 → 0.8.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.
@@ -1,5 +1,5 @@
1
1
  import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
2
- import type { EmptySchema } from "./payload_pb.ts";
2
+ import type { Empty, EmptySchema } from "./payload_pb.ts";
3
3
  import type { Message, UnknownEnum } from "@bufbuild/protobuf";
4
4
  /**
5
5
  * Describes the file ankka/protocol/v1/discovery.proto.
@@ -441,6 +441,12 @@ export type Endpoint = Message<"ankka.protocol.v1.Endpoint"> & {
441
441
  * @generated from field: repeated ankka.protocol.v1.Route routes = 4;
442
442
  */
443
443
  routes: Route[];
444
+ /**
445
+ * Read only when `acl` is CALLERS: the callers admitted, any one of which suffices (protocol 1.1).
446
+ *
447
+ * @generated from field: repeated ankka.protocol.v1.CallerMatcher allow_callers = 5;
448
+ */
449
+ allowCallers: CallerMatcher[];
444
450
  };
445
451
  /**
446
452
  * Describes the message ankka.protocol.v1.Endpoint.
@@ -463,6 +469,10 @@ export declare const Endpoint_Acl: {
463
469
  * @generated from enum value: AUTHENTICATED = 2;
464
470
  */
465
471
  readonly AUTHENTICATED: 2;
472
+ /**
473
+ * @generated from enum value: CALLERS = 3;
474
+ */
475
+ readonly CALLERS: 3;
466
476
  };
467
477
  /**
468
478
  * @generated from enum ankka.protocol.v1.Endpoint.Acl
@@ -472,6 +482,67 @@ export type Endpoint_Acl = (typeof Endpoint_Acl)[keyof typeof Endpoint_Acl] | Un
472
482
  * Describes the enum ankka.protocol.v1.Endpoint.Acl.
473
483
  */
474
484
  export declare const Endpoint_AclSchema: GenEnum<Endpoint_Acl>;
485
+ /**
486
+ * One kind of caller a CALLERS acl admits. A named service with no project means this service's own.
487
+ *
488
+ * @generated from message ankka.protocol.v1.CallerMatcher
489
+ */
490
+ export type CallerMatcher = Message<"ankka.protocol.v1.CallerMatcher"> & {
491
+ /**
492
+ * @generated from oneof ankka.protocol.v1.CallerMatcher.kind
493
+ */
494
+ kind: {
495
+ /**
496
+ * @generated from field: ankka.protocol.v1.Empty internet = 1;
497
+ */
498
+ value: Empty;
499
+ case: "internet";
500
+ } | {
501
+ /**
502
+ * @generated from field: ankka.protocol.v1.NamedService service = 2;
503
+ */
504
+ value: NamedService;
505
+ case: "service";
506
+ } | {
507
+ /**
508
+ * @generated from field: ankka.protocol.v1.Empty any_in_project = 3;
509
+ */
510
+ value: Empty;
511
+ case: "anyInProject";
512
+ } | {
513
+ /**
514
+ * @generated from field: ankka.protocol.v1.Empty self = 4;
515
+ */
516
+ value: Empty;
517
+ case: "self";
518
+ } | {
519
+ case: undefined;
520
+ value?: undefined;
521
+ };
522
+ };
523
+ /**
524
+ * Describes the message ankka.protocol.v1.CallerMatcher.
525
+ * Use `create(CallerMatcherSchema)` to create a new message.
526
+ */
527
+ export declare const CallerMatcherSchema: GenMessage<CallerMatcher>;
528
+ /**
529
+ * @generated from message ankka.protocol.v1.NamedService
530
+ */
531
+ export type NamedService = Message<"ankka.protocol.v1.NamedService"> & {
532
+ /**
533
+ * @generated from field: optional string project = 1;
534
+ */
535
+ project?: string | undefined;
536
+ /**
537
+ * @generated from field: string name = 2;
538
+ */
539
+ name: string;
540
+ };
541
+ /**
542
+ * Describes the message ankka.protocol.v1.NamedService.
543
+ * Use `create(NamedServiceSchema)` to create a new message.
544
+ */
545
+ export declare const NamedServiceSchema: GenMessage<NamedService>;
475
546
  /**
476
547
  * @generated from message ankka.protocol.v1.Route
477
548
  */
@@ -512,6 +583,12 @@ export type Route = Message<"ankka.protocol.v1.Route"> & {
512
583
  * @generated from field: optional ankka.protocol.v1.Endpoint.Acl acl = 6;
513
584
  */
514
585
  acl?: Endpoint_Acl | undefined;
586
+ /**
587
+ * The route's own callers, read only when its `acl` is CALLERS.
588
+ *
589
+ * @generated from field: repeated ankka.protocol.v1.CallerMatcher allow_callers = 7;
590
+ */
591
+ allowCallers: CallerMatcher[];
515
592
  };
516
593
  /**
517
594
  * Describes the message ankka.protocol.v1.Route.
@@ -5,7 +5,7 @@ import { file_ankka_protocol_v1_payload } from "./payload_pb.js";
5
5
  /**
6
6
  * Describes the file ankka/protocol/v1/discovery.proto.
7
7
  */
8
- export const file_ankka_protocol_v1_discovery = /*@__PURE__*/ fileDesc("CiFhbmtrYS9wcm90b2NvbC92MS9kaXNjb3ZlcnkucHJvdG8SEWFua2thLnByb3RvY29sLnYxIkAKC1NpZGVjYXJJbmZvEhgKEHByb3RvY29sX3ZlcnNpb24YASABKAkSFwoPcnVudGltZV92ZXJzaW9uGAIgASgJIqsBCgRTcGVjEhgKEHByb3RvY29sX3ZlcnNpb24YASABKAkSJwoDc2RrGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuU2RrSW5mbxIwCgpjb21wb25lbnRzGAMgAygLMhwuYW5ra2EucHJvdG9jb2wudjEuQ29tcG9uZW50Ei4KCWVuZHBvaW50cxgEIAMoCzIbLmFua2thLnByb3RvY29sLnYxLkVuZHBvaW50IigKB1Nka0luZm8SDAoEbmFtZRgBIAEoCRIPCgd2ZXJzaW9uGAIgASgJIvoDCglDb21wb25lbnQSJQoEa2luZBgBIAEoDjIXLmFua2thLnByb3RvY29sLnYxLktpbmQSCgoCaWQYAiABKAkSLAoIaGFuZGxlcnMYAyADKAsyGi5hbmtrYS5wcm90b2NvbC52MS5IYW5kbGVyEj4KDWV2ZW50X3NvdXJjZWQYCiABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5FdmVudFNvdXJjZWREZXRhaWxIABI2CglrZXlfdmFsdWUYCyABKAsyIS5hbmtrYS5wcm90b2NvbC52MS5LZXlWYWx1ZURldGFpbEgAEjUKCHdvcmtmbG93GAwgASgLMiEuYW5ra2EucHJvdG9jb2wudjEuV29ya2Zsb3dEZXRhaWxIABItCgR2aWV3GA0gASgLMh0uYW5ra2EucHJvdG9jb2wudjEuVmlld0RldGFpbEgAEjUKCGNvbnN1bWVyGA4gASgLMiEuYW5ra2EucHJvdG9jb2wudjEuQ29uc3VtZXJEZXRhaWxIABI8Cgx0aW1lZF9hY3Rpb24YDyABKAsyJC5hbmtrYS5wcm90b2NvbC52MS5UaW1lZEFjdGlvbkRldGFpbEgAEi8KBWFnZW50GBAgASgLMh4uYW5ra2EucHJvdG9jb2wudjEuQWdlbnREZXRhaWxIAEIICgZkZXRhaWwiPQoHSGFuZGxlchIMCgRuYW1lGAEgASgJEhEKCXJlYWRfb25seRgCIAEoCBIRCglzdHJlYW1pbmcYAyABKAgiLAoSRXZlbnRTb3VyY2VkRGV0YWlsEhYKDnNuYXBzaG90X2V2ZXJ5GAEgASgFIhAKDktleVZhbHVlRGV0YWlsIv8ECg5Xb3JrZmxvd0RldGFpbBINCgVzdGVwcxgBIAMoCRJBCghzZXR0aW5ncxgCIAEoCzIqLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93RGV0YWlsLlNldHRpbmdzSACIAQEaowIKCFNldHRpbmdzEhsKDnRpbWVvdXRfbWlsbGlzGAEgASgDSACIAQESKAobZGVmYXVsdF9zdGVwX3RpbWVvdXRfbWlsbGlzGAIgASgDSAGIAQESSQoQZGVmYXVsdF9yZWNvdmVyeRgDIAEoCzIqLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93RGV0YWlsLlJlY292ZXJ5SAKIAQESPQoFc3RlcHMYBCADKAsyLi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0RldGFpbC5TdGVwU2V0dGluZ3NCEQoPX3RpbWVvdXRfbWlsbGlzQh4KHF9kZWZhdWx0X3N0ZXBfdGltZW91dF9taWxsaXNCEwoRX2RlZmF1bHRfcmVjb3ZlcnkanAEKDFN0ZXBTZXR0aW5ncxIMCgRzdGVwGAEgASgJEhsKDnRpbWVvdXRfbWlsbGlzGAIgASgDSACIAQESQQoIcmVjb3ZlcnkYAyABKAsyKi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0RldGFpbC5SZWNvdmVyeUgBiAEBQhEKD190aW1lb3V0X21pbGxpc0ILCglfcmVjb3ZlcnkaSQoIUmVjb3ZlcnkSEwoLbWF4X3JldHJpZXMYASABKAUSGAoLZmFpbG92ZXJfdG8YAiABKAlIAIgBAUIOCgxfZmFpbG92ZXJfdG9CCwoJX3NldHRpbmdzIqMBCgZTb3VyY2USOwoJY29tcG9uZW50GAEgASgLMiYuYW5ra2EucHJvdG9jb2wudjEuU291cmNlLkNvbXBvbmVudFJlZkgAEg8KBXRvcGljGAIgASgJSAAaQQoMQ29tcG9uZW50UmVmEiUKBGtpbmQYASABKA4yFy5hbmtrYS5wcm90b2NvbC52MS5LaW5kEgoKAmlkGAIgASgJQggKBnNvdXJjZSJeCgpWaWV3RGV0YWlsEikKBnNvdXJjZRgBIAEoCzIZLmFua2thLnByb3RvY29sLnYxLlNvdXJjZRIUCgxyb3dfbWFuaWZlc3QYAiABKAkSDwoHcXVlcmllcxgDIAMoCSJlCg5Db25zdW1lckRldGFpbBIpCgZzb3VyY2UYASABKAsyGS5hbmtrYS5wcm90b2NvbC52MS5Tb3VyY2USGAoLcHJvZHVjZXNfdG8YAiABKAlIAIgBAUIOCgxfcHJvZHVjZXNfdG8iEwoRVGltZWRBY3Rpb25EZXRhaWwidAoLQWdlbnREZXRhaWwSDAoEcm9sZRgBIAEoCRIbChNtYXhfdG9vbF9jYWxsX3N0ZXBzGAIgASgFEiYKBXRvb2xzGAMgAygLMhcuYW5ra2EucHJvdG9jb2wudjEuVG9vbBISCgpndWFyZHJhaWxzGAQgAygJIkQKBFRvb2wSDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIZChFpbnB1dF9zY2hlbWFfanNvbhgDIAEoCSK1AQoIRW5kcG9pbnQSCgoCaWQYASABKAkSDgoGcHJlZml4GAIgASgJEiwKA2FjbBgDIAEoDjIfLmFua2thLnByb3RvY29sLnYxLkVuZHBvaW50LkFjbBIoCgZyb3V0ZXMYBCADKAsyGC5hbmtrYS5wcm90b2NvbC52MS5Sb3V0ZSI1CgNBY2wSDQoJQUxMT1dfQUxMEAASDAoIREVOWV9BTEwQARIRCg1BVVRIRU5USUNBVEVEEAIilQEKBVJvdXRlEgoKAmlkGAEgASgJEg4KBm1ldGhvZBgCIAEoCRIQCgh0ZW1wbGF0ZRgDIAEoCRIQCghoYXNfYm9keRgEIAEoCBIRCglzdHJlYW1pbmcYBSABKAgSMQoDYWNsGAYgASgOMh8uYW5ra2EucHJvdG9jb2wudjEuRW5kcG9pbnQuQWNsSACIAQFCBgoEX2FjbCIaCgdQcm9ibGVtEg8KB21lc3NhZ2UYASABKAkqeQoES2luZBIYChRFVkVOVF9TT1VSQ0VEX0VOVElUWRAAEhQKEEtFWV9WQUxVRV9FTlRJVFkQARIMCghXT1JLRkxPVxACEggKBFZJRVcQAxIMCghDT05TVU1FUhAEEhAKDFRJTUVEX0FDVElPThAFEgkKBUFHRU5UEAYylQEKCURpc2NvdmVyeRJDCghEaXNjb3ZlchIeLmFua2thLnByb3RvY29sLnYxLlNpZGVjYXJJbmZvGhcuYW5ra2EucHJvdG9jb2wudjEuU3BlYxJDCgtSZXBvcnRFcnJvchIaLmFua2thLnByb3RvY29sLnYxLlByb2JsZW0aGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eWIGcHJvdG8z", [file_ankka_protocol_v1_payload]);
8
+ export const file_ankka_protocol_v1_discovery = /*@__PURE__*/ fileDesc("CiFhbmtrYS9wcm90b2NvbC92MS9kaXNjb3ZlcnkucHJvdG8SEWFua2thLnByb3RvY29sLnYxIkAKC1NpZGVjYXJJbmZvEhgKEHByb3RvY29sX3ZlcnNpb24YASABKAkSFwoPcnVudGltZV92ZXJzaW9uGAIgASgJIqsBCgRTcGVjEhgKEHByb3RvY29sX3ZlcnNpb24YASABKAkSJwoDc2RrGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuU2RrSW5mbxIwCgpjb21wb25lbnRzGAMgAygLMhwuYW5ra2EucHJvdG9jb2wudjEuQ29tcG9uZW50Ei4KCWVuZHBvaW50cxgEIAMoCzIbLmFua2thLnByb3RvY29sLnYxLkVuZHBvaW50IigKB1Nka0luZm8SDAoEbmFtZRgBIAEoCRIPCgd2ZXJzaW9uGAIgASgJIvoDCglDb21wb25lbnQSJQoEa2luZBgBIAEoDjIXLmFua2thLnByb3RvY29sLnYxLktpbmQSCgoCaWQYAiABKAkSLAoIaGFuZGxlcnMYAyADKAsyGi5hbmtrYS5wcm90b2NvbC52MS5IYW5kbGVyEj4KDWV2ZW50X3NvdXJjZWQYCiABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5FdmVudFNvdXJjZWREZXRhaWxIABI2CglrZXlfdmFsdWUYCyABKAsyIS5hbmtrYS5wcm90b2NvbC52MS5LZXlWYWx1ZURldGFpbEgAEjUKCHdvcmtmbG93GAwgASgLMiEuYW5ra2EucHJvdG9jb2wudjEuV29ya2Zsb3dEZXRhaWxIABItCgR2aWV3GA0gASgLMh0uYW5ra2EucHJvdG9jb2wudjEuVmlld0RldGFpbEgAEjUKCGNvbnN1bWVyGA4gASgLMiEuYW5ra2EucHJvdG9jb2wudjEuQ29uc3VtZXJEZXRhaWxIABI8Cgx0aW1lZF9hY3Rpb24YDyABKAsyJC5hbmtrYS5wcm90b2NvbC52MS5UaW1lZEFjdGlvbkRldGFpbEgAEi8KBWFnZW50GBAgASgLMh4uYW5ra2EucHJvdG9jb2wudjEuQWdlbnREZXRhaWxIAEIICgZkZXRhaWwiPQoHSGFuZGxlchIMCgRuYW1lGAEgASgJEhEKCXJlYWRfb25seRgCIAEoCBIRCglzdHJlYW1pbmcYAyABKAgiLAoSRXZlbnRTb3VyY2VkRGV0YWlsEhYKDnNuYXBzaG90X2V2ZXJ5GAEgASgFIhAKDktleVZhbHVlRGV0YWlsIv8ECg5Xb3JrZmxvd0RldGFpbBINCgVzdGVwcxgBIAMoCRJBCghzZXR0aW5ncxgCIAEoCzIqLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93RGV0YWlsLlNldHRpbmdzSACIAQEaowIKCFNldHRpbmdzEhsKDnRpbWVvdXRfbWlsbGlzGAEgASgDSACIAQESKAobZGVmYXVsdF9zdGVwX3RpbWVvdXRfbWlsbGlzGAIgASgDSAGIAQESSQoQZGVmYXVsdF9yZWNvdmVyeRgDIAEoCzIqLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93RGV0YWlsLlJlY292ZXJ5SAKIAQESPQoFc3RlcHMYBCADKAsyLi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0RldGFpbC5TdGVwU2V0dGluZ3NCEQoPX3RpbWVvdXRfbWlsbGlzQh4KHF9kZWZhdWx0X3N0ZXBfdGltZW91dF9taWxsaXNCEwoRX2RlZmF1bHRfcmVjb3ZlcnkanAEKDFN0ZXBTZXR0aW5ncxIMCgRzdGVwGAEgASgJEhsKDnRpbWVvdXRfbWlsbGlzGAIgASgDSACIAQESQQoIcmVjb3ZlcnkYAyABKAsyKi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0RldGFpbC5SZWNvdmVyeUgBiAEBQhEKD190aW1lb3V0X21pbGxpc0ILCglfcmVjb3ZlcnkaSQoIUmVjb3ZlcnkSEwoLbWF4X3JldHJpZXMYASABKAUSGAoLZmFpbG92ZXJfdG8YAiABKAlIAIgBAUIOCgxfZmFpbG92ZXJfdG9CCwoJX3NldHRpbmdzIqMBCgZTb3VyY2USOwoJY29tcG9uZW50GAEgASgLMiYuYW5ra2EucHJvdG9jb2wudjEuU291cmNlLkNvbXBvbmVudFJlZkgAEg8KBXRvcGljGAIgASgJSAAaQQoMQ29tcG9uZW50UmVmEiUKBGtpbmQYASABKA4yFy5hbmtrYS5wcm90b2NvbC52MS5LaW5kEgoKAmlkGAIgASgJQggKBnNvdXJjZSJeCgpWaWV3RGV0YWlsEikKBnNvdXJjZRgBIAEoCzIZLmFua2thLnByb3RvY29sLnYxLlNvdXJjZRIUCgxyb3dfbWFuaWZlc3QYAiABKAkSDwoHcXVlcmllcxgDIAMoCSJlCg5Db25zdW1lckRldGFpbBIpCgZzb3VyY2UYASABKAsyGS5hbmtrYS5wcm90b2NvbC52MS5Tb3VyY2USGAoLcHJvZHVjZXNfdG8YAiABKAlIAIgBAUIOCgxfcHJvZHVjZXNfdG8iEwoRVGltZWRBY3Rpb25EZXRhaWwidAoLQWdlbnREZXRhaWwSDAoEcm9sZRgBIAEoCRIbChNtYXhfdG9vbF9jYWxsX3N0ZXBzGAIgASgFEiYKBXRvb2xzGAMgAygLMhcuYW5ra2EucHJvdG9jb2wudjEuVG9vbBISCgpndWFyZHJhaWxzGAQgAygJIkQKBFRvb2wSDAoEbmFtZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIZChFpbnB1dF9zY2hlbWFfanNvbhgDIAEoCSL7AQoIRW5kcG9pbnQSCgoCaWQYASABKAkSDgoGcHJlZml4GAIgASgJEiwKA2FjbBgDIAEoDjIfLmFua2thLnByb3RvY29sLnYxLkVuZHBvaW50LkFjbBIoCgZyb3V0ZXMYBCADKAsyGC5hbmtrYS5wcm90b2NvbC52MS5Sb3V0ZRI3Cg1hbGxvd19jYWxsZXJzGAUgAygLMiAuYW5ra2EucHJvdG9jb2wudjEuQ2FsbGVyTWF0Y2hlciJCCgNBY2wSDQoJQUxMT1dfQUxMEAASDAoIREVOWV9BTEwQARIRCg1BVVRIRU5USUNBVEVEEAISCwoHQ0FMTEVSUxADItcBCg1DYWxsZXJNYXRjaGVyEiwKCGludGVybmV0GAEgASgLMhguYW5ra2EucHJvdG9jb2wudjEuRW1wdHlIABIyCgdzZXJ2aWNlGAIgASgLMh8uYW5ra2EucHJvdG9jb2wudjEuTmFtZWRTZXJ2aWNlSAASMgoOYW55X2luX3Byb2plY3QYAyABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAEigKBHNlbGYYBCABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAQgYKBGtpbmQiPgoMTmFtZWRTZXJ2aWNlEhQKB3Byb2plY3QYASABKAlIAIgBARIMCgRuYW1lGAIgASgJQgoKCF9wcm9qZWN0Is4BCgVSb3V0ZRIKCgJpZBgBIAEoCRIOCgZtZXRob2QYAiABKAkSEAoIdGVtcGxhdGUYAyABKAkSEAoIaGFzX2JvZHkYBCABKAgSEQoJc3RyZWFtaW5nGAUgASgIEjEKA2FjbBgGIAEoDjIfLmFua2thLnByb3RvY29sLnYxLkVuZHBvaW50LkFjbEgAiAEBEjcKDWFsbG93X2NhbGxlcnMYByADKAsyIC5hbmtrYS5wcm90b2NvbC52MS5DYWxsZXJNYXRjaGVyQgYKBF9hY2wiGgoHUHJvYmxlbRIPCgdtZXNzYWdlGAEgASgJKnkKBEtpbmQSGAoURVZFTlRfU09VUkNFRF9FTlRJVFkQABIUChBLRVlfVkFMVUVfRU5USVRZEAESDAoIV09SS0ZMT1cQAhIICgRWSUVXEAMSDAoIQ09OU1VNRVIQBBIQCgxUSU1FRF9BQ1RJT04QBRIJCgVBR0VOVBAGMpUBCglEaXNjb3ZlcnkSQwoIRGlzY292ZXISHi5hbmtrYS5wcm90b2NvbC52MS5TaWRlY2FySW5mbxoXLmFua2thLnByb3RvY29sLnYxLlNwZWMSQwoLUmVwb3J0RXJyb3ISGi5hbmtrYS5wcm90b2NvbC52MS5Qcm9ibGVtGhguYW5ra2EucHJvdG9jb2wudjEuRW1wdHliBnByb3RvMw", [file_ankka_protocol_v1_payload]);
9
9
  /**
10
10
  * Describes the message ankka.protocol.v1.SidecarInfo.
11
11
  * Use `create(SidecarInfoSchema)` to create a new message.
@@ -117,21 +117,35 @@ export const Endpoint_Acl = {
117
117
  * @generated from enum value: AUTHENTICATED = 2;
118
118
  */
119
119
  AUTHENTICATED: 2,
120
+ /**
121
+ * @generated from enum value: CALLERS = 3;
122
+ */
123
+ CALLERS: 3,
120
124
  };
121
125
  /**
122
126
  * Describes the enum ankka.protocol.v1.Endpoint.Acl.
123
127
  */
124
128
  export const Endpoint_AclSchema = /*@__PURE__*/ enumDesc(file_ankka_protocol_v1_discovery, 14, 0);
129
+ /**
130
+ * Describes the message ankka.protocol.v1.CallerMatcher.
131
+ * Use `create(CallerMatcherSchema)` to create a new message.
132
+ */
133
+ export const CallerMatcherSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 15);
134
+ /**
135
+ * Describes the message ankka.protocol.v1.NamedService.
136
+ * Use `create(NamedServiceSchema)` to create a new message.
137
+ */
138
+ export const NamedServiceSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 16);
125
139
  /**
126
140
  * Describes the message ankka.protocol.v1.Route.
127
141
  * Use `create(RouteSchema)` to create a new message.
128
142
  */
129
- export const RouteSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 15);
143
+ export const RouteSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 17);
130
144
  /**
131
145
  * Describes the message ankka.protocol.v1.Problem.
132
146
  * Use `create(ProblemSchema)` to create a new message.
133
147
  */
134
- export const ProblemSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 16);
148
+ export const ProblemSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_discovery, 18);
135
149
  /**
136
150
  * @generated from enum ankka.protocol.v1.Kind
137
151
  */
@@ -57,6 +57,13 @@ export type HttpRequest = Message<"ankka.protocol.v1.HttpRequest"> & {
57
57
  * @generated from field: ankka.protocol.v1.Metadata metadata = 9;
58
58
  */
59
59
  metadata?: Metadata | undefined;
60
+ /**
61
+ * Which workload sent the request, as the platform established it from the client certificate
62
+ * (protocol 1.1). Absent from a sidecar that predates it, which a process reads as local.
63
+ *
64
+ * @generated from field: optional ankka.protocol.v1.Caller caller = 10;
65
+ */
66
+ caller?: Caller | undefined;
60
67
  };
61
68
  /**
62
69
  * Describes the message ankka.protocol.v1.HttpRequest.
@@ -81,6 +88,62 @@ export type HttpRequest_Pair = Message<"ankka.protocol.v1.HttpRequest.Pair"> & {
81
88
  * Use `create(HttpRequest_PairSchema)` to create a new message.
82
89
  */
83
90
  export declare const HttpRequest_PairSchema: GenMessage<HttpRequest_Pair>;
91
+ /**
92
+ * The gateway (the internet), a named service of this installation, or — outside a cluster — the
93
+ * local machine. Never taken from anything the request says about itself.
94
+ *
95
+ * @generated from message ankka.protocol.v1.Caller
96
+ */
97
+ export type Caller = Message<"ankka.protocol.v1.Caller"> & {
98
+ /**
99
+ * @generated from oneof ankka.protocol.v1.Caller.kind
100
+ */
101
+ kind: {
102
+ /**
103
+ * @generated from field: ankka.protocol.v1.Empty gateway = 1;
104
+ */
105
+ value: Empty;
106
+ case: "gateway";
107
+ } | {
108
+ /**
109
+ * @generated from field: ankka.protocol.v1.ServiceCaller service = 2;
110
+ */
111
+ value: ServiceCaller;
112
+ case: "service";
113
+ } | {
114
+ /**
115
+ * @generated from field: ankka.protocol.v1.Empty local = 3;
116
+ */
117
+ value: Empty;
118
+ case: "local";
119
+ } | {
120
+ case: undefined;
121
+ value?: undefined;
122
+ };
123
+ };
124
+ /**
125
+ * Describes the message ankka.protocol.v1.Caller.
126
+ * Use `create(CallerSchema)` to create a new message.
127
+ */
128
+ export declare const CallerSchema: GenMessage<Caller>;
129
+ /**
130
+ * @generated from message ankka.protocol.v1.ServiceCaller
131
+ */
132
+ export type ServiceCaller = Message<"ankka.protocol.v1.ServiceCaller"> & {
133
+ /**
134
+ * @generated from field: string project = 1;
135
+ */
136
+ project: string;
137
+ /**
138
+ * @generated from field: string name = 2;
139
+ */
140
+ name: string;
141
+ };
142
+ /**
143
+ * Describes the message ankka.protocol.v1.ServiceCaller.
144
+ * Use `create(ServiceCallerSchema)` to create a new message.
145
+ */
146
+ export declare const ServiceCallerSchema: GenMessage<ServiceCaller>;
84
147
  /**
85
148
  * @generated from message ankka.protocol.v1.Principal
86
149
  */
@@ -7,7 +7,7 @@ import { file_ankka_protocol_v1_payload } from "./payload_pb.js";
7
7
  /**
8
8
  * Describes the file ankka/protocol/v1/endpoint.proto.
9
9
  */
10
- export const file_ankka_protocol_v1_endpoint = /*@__PURE__*/ fileDesc("CiBhbmtrYS9wcm90b2NvbC92MS9lbmRwb2ludC5wcm90bxIRYW5ra2EucHJvdG9jb2wudjEi7QIKC0h0dHBSZXF1ZXN0EhMKC2VuZHBvaW50X2lkGAEgASgJEhAKCHJvdXRlX2lkGAIgASgJEhEKCXBhdGhfYXJncxgDIAMoCRIyCgVxdWVyeRgEIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXISNAoHaGVhZGVycxgFIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXISFAoMY29udGVudF90eXBlGAYgASgJEgwKBGJvZHkYByABKAwSNAoJcHJpbmNpcGFsGAggASgLMhwuYW5ra2EucHJvdG9jb2wudjEuUHJpbmNpcGFsSACIAQESLQoIbWV0YWRhdGEYCSABKAsyGy5hbmtrYS5wcm90b2NvbC52MS5NZXRhZGF0YRojCgRQYWlyEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAlCDAoKX3ByaW5jaXBhbCJ9CglQcmluY2lwYWwSDwoHc3ViamVjdBgBIAEoCRIRCgRuYW1lGAIgASgJSACIAQESEgoFZW1haWwYAyABKAlIAYgBARIWCg5lbWFpbF92ZXJpZmllZBgEIAEoCBINCgVyb2xlcxgFIAMoCUIHCgVfbmFtZUIICgZfZW1haWwiegoJSHR0cFJlcGx5EjMKCHJlc3BvbnNlGAEgASgLMh8uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlc3BvbnNlSAASLQoHZmFpbHVyZRgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLkZhaWx1cmVIAEIJCgdtZXNzYWdlIngKDEh0dHBSZXNwb25zZRIOCgZzdGF0dXMYASABKAUSFAoMY29udGVudF90eXBlGAIgASgJEgwKBGJvZHkYAyABKAwSNAoHaGVhZGVycxgEIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXIigQEKC1N0cmVhbUZyYW1lEg4KBHRleHQYASABKAlIABItCgljb21wbGV0ZWQYAiABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAEioKBmZhaWxlZBgDIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVycm9ySABCBwoFZnJhbWUyoAEKBEh0dHASRgoGSGFuZGxlEh4uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlcXVlc3QaHC5hbmtrYS5wcm90b2NvbC52MS5IdHRwUmVwbHkSUAoMSGFuZGxlU3RyZWFtEh4uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlcXVlc3QaHi5hbmtrYS5wcm90b2NvbC52MS5TdHJlYW1GcmFtZTABYgZwcm90bzM", [file_ankka_protocol_v1_payload]);
10
+ export const file_ankka_protocol_v1_endpoint = /*@__PURE__*/ fileDesc("CiBhbmtrYS9wcm90b2NvbC92MS9lbmRwb2ludC5wcm90bxIRYW5ra2EucHJvdG9jb2wudjEiqAMKC0h0dHBSZXF1ZXN0EhMKC2VuZHBvaW50X2lkGAEgASgJEhAKCHJvdXRlX2lkGAIgASgJEhEKCXBhdGhfYXJncxgDIAMoCRIyCgVxdWVyeRgEIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXISNAoHaGVhZGVycxgFIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXISFAoMY29udGVudF90eXBlGAYgASgJEgwKBGJvZHkYByABKAwSNAoJcHJpbmNpcGFsGAggASgLMhwuYW5ra2EucHJvdG9jb2wudjEuUHJpbmNpcGFsSACIAQESLQoIbWV0YWRhdGEYCSABKAsyGy5hbmtrYS5wcm90b2NvbC52MS5NZXRhZGF0YRIuCgZjYWxsZXIYCiABKAsyGS5hbmtrYS5wcm90b2NvbC52MS5DYWxsZXJIAYgBARojCgRQYWlyEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAlCDAoKX3ByaW5jaXBhbEIJCgdfY2FsbGVyIp0BCgZDYWxsZXISKwoHZ2F0ZXdheRgBIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVtcHR5SAASMwoHc2VydmljZRgCIAEoCzIgLmFua2thLnByb3RvY29sLnYxLlNlcnZpY2VDYWxsZXJIABIpCgVsb2NhbBgDIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVtcHR5SABCBgoEa2luZCIuCg1TZXJ2aWNlQ2FsbGVyEg8KB3Byb2plY3QYASABKAkSDAoEbmFtZRgCIAEoCSJ9CglQcmluY2lwYWwSDwoHc3ViamVjdBgBIAEoCRIRCgRuYW1lGAIgASgJSACIAQESEgoFZW1haWwYAyABKAlIAYgBARIWCg5lbWFpbF92ZXJpZmllZBgEIAEoCBINCgVyb2xlcxgFIAMoCUIHCgVfbmFtZUIICgZfZW1haWwiegoJSHR0cFJlcGx5EjMKCHJlc3BvbnNlGAEgASgLMh8uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlc3BvbnNlSAASLQoHZmFpbHVyZRgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLkZhaWx1cmVIAEIJCgdtZXNzYWdlIngKDEh0dHBSZXNwb25zZRIOCgZzdGF0dXMYASABKAUSFAoMY29udGVudF90eXBlGAIgASgJEgwKBGJvZHkYAyABKAwSNAoHaGVhZGVycxgEIAMoCzIjLmFua2thLnByb3RvY29sLnYxLkh0dHBSZXF1ZXN0LlBhaXIigQEKC1N0cmVhbUZyYW1lEg4KBHRleHQYASABKAlIABItCgljb21wbGV0ZWQYAiABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAEioKBmZhaWxlZBgDIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVycm9ySABCBwoFZnJhbWUyoAEKBEh0dHASRgoGSGFuZGxlEh4uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlcXVlc3QaHC5hbmtrYS5wcm90b2NvbC52MS5IdHRwUmVwbHkSUAoMSGFuZGxlU3RyZWFtEh4uYW5ra2EucHJvdG9jb2wudjEuSHR0cFJlcXVlc3QaHi5hbmtrYS5wcm90b2NvbC52MS5TdHJlYW1GcmFtZTABYgZwcm90bzM", [file_ankka_protocol_v1_payload]);
11
11
  /**
12
12
  * Describes the message ankka.protocol.v1.HttpRequest.
13
13
  * Use `create(HttpRequestSchema)` to create a new message.
@@ -18,26 +18,36 @@ export const HttpRequestSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v
18
18
  * Use `create(HttpRequest_PairSchema)` to create a new message.
19
19
  */
20
20
  export const HttpRequest_PairSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 0, 0);
21
+ /**
22
+ * Describes the message ankka.protocol.v1.Caller.
23
+ * Use `create(CallerSchema)` to create a new message.
24
+ */
25
+ export const CallerSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 1);
26
+ /**
27
+ * Describes the message ankka.protocol.v1.ServiceCaller.
28
+ * Use `create(ServiceCallerSchema)` to create a new message.
29
+ */
30
+ export const ServiceCallerSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 2);
21
31
  /**
22
32
  * Describes the message ankka.protocol.v1.Principal.
23
33
  * Use `create(PrincipalSchema)` to create a new message.
24
34
  */
25
- export const PrincipalSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 1);
35
+ export const PrincipalSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 3);
26
36
  /**
27
37
  * Describes the message ankka.protocol.v1.HttpReply.
28
38
  * Use `create(HttpReplySchema)` to create a new message.
29
39
  */
30
- export const HttpReplySchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 2);
40
+ export const HttpReplySchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 4);
31
41
  /**
32
42
  * Describes the message ankka.protocol.v1.HttpResponse.
33
43
  * Use `create(HttpResponseSchema)` to create a new message.
34
44
  */
35
- export const HttpResponseSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 3);
45
+ export const HttpResponseSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 5);
36
46
  /**
37
47
  * Describes the message ankka.protocol.v1.StreamFrame.
38
48
  * Use `create(StreamFrameSchema)` to create a new message.
39
49
  */
40
- export const StreamFrameSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 4);
50
+ export const StreamFrameSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_endpoint, 6);
41
51
  /**
42
52
  * @generated from service ankka.protocol.v1.Http
43
53
  */
package/dist/context.d.ts CHANGED
@@ -27,6 +27,19 @@ export interface Principal {
27
27
  readonly emailVerified: boolean;
28
28
  readonly roles: readonly string[];
29
29
  }
30
+ /**
31
+ * Which workload sent a request, as the platform established it from the client certificate: the gateway
32
+ * (the internet), a named service, or — outside a cluster, where there is no certificate — the local machine.
33
+ */
34
+ export type Caller = {
35
+ readonly kind: "gateway";
36
+ } | {
37
+ readonly kind: "service";
38
+ readonly project: string;
39
+ readonly name: string;
40
+ } | {
41
+ readonly kind: "local";
42
+ };
30
43
  /** Query parameters in request order; a name may repeat. */
31
44
  export declare class Query {
32
45
  private readonly pairs;
@@ -52,6 +65,8 @@ export interface RequestContext<P = Readonly<Record<string, unknown>>> {
52
65
  /** The caller, when the route's access rule is `authenticated`; `null` otherwise. */
53
66
  readonly principal: Principal | null;
54
67
  readonly metadata: Metadata;
68
+ /** Which workload sent the request. Always present; see `Caller`. */
69
+ readonly caller: Caller;
55
70
  }
56
71
  /** Runs `fn` with `request` as the current request, for the asynchronous work it starts. */
57
72
  export declare function withRequest<T>(request: RequestContext, fn: () => T): T;
package/dist/index.d.ts CHANGED
@@ -18,8 +18,8 @@ export { TimedAction, type TimedActionClass } from "./timedAction.ts";
18
18
  export { AgentEffects, type AgentEffect } from "./effects/agent.ts";
19
19
  export { Agent, type AgentClass } from "./agent.ts";
20
20
  export { Endpoint, type EndpointClass } from "./endpoint.ts";
21
- export { Acl, HttpProblem, get, post, put, patch, del, sse, type RouteRef, type RouteOptions, type RouteTable, type Params, type ParamNames, type HttpMethod } from "./routes.ts";
22
- export { type CommandContext, type RequestContext, type Principal, Query, Headers } from "./context.ts";
21
+ export { Acl, Callers, type CallerMatcher, type CallersAcl, HttpProblem, get, post, put, patch, del, sse, type RouteRef, type RouteOptions, type RouteTable, type Params, type ParamNames, type HttpMethod } from "./routes.ts";
22
+ export { type CommandContext, type RequestContext, type Principal, type Caller, Query, Headers } from "./context.ts";
23
23
  export { ComponentClient, Calls, TypedCalls, Invocation, Views, Timers, type TimerTarget, type ComponentRef } from "./client.ts";
24
24
  export { Ankka, ServiceBuilder, Registry, RegistrationError, type ServiceOptions, type RegisteredComponent, type RegisteredEndpoint, type Source, type RegisteredEventSourced, type RegisteredKeyValue, type RegisteredWorkflow, type RegisteredView, type RegisteredConsumer, type RegisteredTimedAction, type RegisteredAgent, } from "./service.ts";
25
25
  export { Server, type ServerOptions } from "./server/server.ts";
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ export { TimedAction } from "./timedAction.js";
29
29
  export { AgentEffects } from "./effects/agent.js";
30
30
  export { Agent } from "./agent.js";
31
31
  export { Endpoint } from "./endpoint.js";
32
- export { Acl, HttpProblem, get, post, put, patch, del, sse } from "./routes.js";
32
+ export { Acl, Callers, HttpProblem, get, post, put, patch, del, sse } from "./routes.js";
33
33
  export { Query, Headers } from "./context.js";
34
34
  export { ComponentClient, Calls, TypedCalls, Invocation, Views, Timers } from "./client.js";
35
35
  export { Ankka, ServiceBuilder, Registry, RegistrationError, } from "./service.js";
package/dist/routes.d.ts CHANGED
@@ -1,13 +1,49 @@
1
1
  import type { Shape } from "./codec.ts";
2
2
  import type { RequestContext } from "./context.ts";
3
3
  import type { Infer, Schema } from "./schema.ts";
4
- /** Who may call: everyone, no one, or authenticated callers only. There is no default. */
4
+ /** One kind of caller an `Acl.allowCallers` admits; build one through `Callers`. */
5
+ export type CallerMatcher = {
6
+ readonly kind: "internet";
7
+ } | {
8
+ readonly kind: "service";
9
+ readonly name: string;
10
+ readonly project?: string;
11
+ } | {
12
+ readonly kind: "anyInProject";
13
+ } | {
14
+ readonly kind: "self";
15
+ };
16
+ /**
17
+ * The callers an endpoint can name: `Acl.allowCallers(Callers.internet, Callers.service("orders"))`. A named
18
+ * service is in this service's own project unless `project` names another.
19
+ */
20
+ export declare const Callers: Readonly<{
21
+ internet: CallerMatcher;
22
+ anyInProject: CallerMatcher;
23
+ self: CallerMatcher;
24
+ service(name: string, options?: {
25
+ readonly project?: string;
26
+ }): CallerMatcher;
27
+ }>;
28
+ /** Only the callers named. In a cluster the caller is read from the certificate the platform issued. */
29
+ export interface CallersAcl {
30
+ readonly kind: "callers";
31
+ readonly callers: readonly CallerMatcher[];
32
+ }
33
+ /**
34
+ * Who may call: everyone, no one, authenticated callers only, or only the callers named. There is no default.
35
+ *
36
+ * Outside a cluster every caller is `{ kind: "local" }`, and `allowCallers` admits it.
37
+ */
38
+ export type Acl = "allow-all" | "deny-all" | "authenticated" | CallersAcl;
5
39
  export declare const Acl: Readonly<{
6
- readonly allowAll: "allow-all";
7
- readonly denyAll: "deny-all";
8
- readonly authenticated: "authenticated";
40
+ allowAll: Acl;
41
+ denyAll: Acl;
42
+ authenticated: Acl;
43
+ allowCallers(first: CallerMatcher, ...rest: CallerMatcher[]): Acl;
9
44
  }>;
10
- export type Acl = (typeof Acl)[keyof typeof Acl];
45
+ /** Whether `x` is an access rule: one of the three words, or a non-empty callers rule. */
46
+ export declare function isAcl(x: unknown): x is Acl;
11
47
  /** Thrown from a route handler to answer a status other than 200 with a plain-text message. */
12
48
  export declare class HttpProblem extends Error {
13
49
  readonly status: number;
package/dist/routes.js CHANGED
@@ -9,12 +9,35 @@
9
9
  //
10
10
  // `req.params` is typed from the template: "/{cartId}/items" gives { cartId: string }.
11
11
  import { isCodec } from "./codec.js";
12
- /** Who may call: everyone, no one, or authenticated callers only. There is no default. */
12
+ /**
13
+ * The callers an endpoint can name: `Acl.allowCallers(Callers.internet, Callers.service("orders"))`. A named
14
+ * service is in this service's own project unless `project` names another.
15
+ */
16
+ export const Callers = Object.freeze({
17
+ internet: Object.freeze({ kind: "internet" }),
18
+ anyInProject: Object.freeze({ kind: "anyInProject" }),
19
+ self: Object.freeze({ kind: "self" }),
20
+ service(name, options) {
21
+ return Object.freeze(options?.project !== undefined ? { kind: "service", name, project: options.project } : { kind: "service", name });
22
+ },
23
+ });
13
24
  export const Acl = Object.freeze({
14
25
  allowAll: "allow-all",
15
26
  denyAll: "deny-all",
16
27
  authenticated: "authenticated",
28
+ allowCallers(first, ...rest) {
29
+ return Object.freeze({ kind: "callers", callers: Object.freeze([first, ...rest]) });
30
+ },
17
31
  });
32
+ /** Whether `x` is an access rule: one of the three words, or a non-empty callers rule. */
33
+ export function isAcl(x) {
34
+ if (x === "allow-all" || x === "deny-all" || x === "authenticated")
35
+ return true;
36
+ if (typeof x !== "object" || x === null)
37
+ return false;
38
+ const rule = x;
39
+ return rule.kind === "callers" && Array.isArray(rule.callers) && rule.callers.length > 0;
40
+ }
18
41
  /** Thrown from a route handler to answer a status other than 200 with a plain-text message. */
19
42
  export class HttpProblem extends Error {
20
43
  status;
@@ -30,6 +30,18 @@ function principalOf(req) {
30
30
  return null;
31
31
  return Object.freeze({ subject: p.subject, name: p.name ?? null, email: p.email ?? null, emailVerified: p.emailVerified, roles: Object.freeze([...p.roles]) });
32
32
  }
33
+ /** The caller the sidecar established; a sidecar that predates protocol 1.1 sends none, which reads as local. */
34
+ function callerOf(req) {
35
+ const kind = req.caller?.kind;
36
+ switch (kind?.case) {
37
+ case "gateway":
38
+ return Object.freeze({ kind: "gateway" });
39
+ case "service":
40
+ return Object.freeze({ kind: "service", project: kind.value.project, name: kind.value.name });
41
+ default:
42
+ return Object.freeze({ kind: "local" });
43
+ }
44
+ }
33
45
  /** A path parameter as its declared schema: strings as they are, scalars through their text codec. */
34
46
  function parseParam(name, text, shape) {
35
47
  if (!shape)
@@ -82,6 +94,7 @@ export function createHttpDispatcher(ctx) {
82
94
  headers: new Headers(req.headers.map((p) => [p.name, p.value])),
83
95
  principal: principalOf(req),
84
96
  metadata: metadataFromProto(req.metadata),
97
+ caller: callerOf(req),
85
98
  });
86
99
  const body = route.body ? codecFor(route.body).decode(req.body) : undefined;
87
100
  return { ok: true, prepared: { endpoint, route, instance, request, body } };
package/dist/service.js CHANGED
@@ -12,7 +12,7 @@ import { Consumer } from "./consumer.js";
12
12
  import { TimedAction } from "./timedAction.js";
13
13
  import { Agent } from "./agent.js";
14
14
  import { Endpoint } from "./endpoint.js";
15
- import { Acl as AclValues } from "./routes.js";
15
+ import { isAcl } from "./routes.js";
16
16
  import { ComponentClient } from "./client.js";
17
17
  import { Server } from "./server/server.js";
18
18
  import { renderSpec } from "./spec.js";
@@ -347,8 +347,8 @@ function registerEndpoint(cls, problems) {
347
347
  if (typeof cls.prefix !== "string" || !cls.prefix.startsWith("/") || (cls.prefix.length > 1 && cls.prefix.endsWith("/"))) {
348
348
  fail(`needs a static prefix starting with "/" and not ending with one, not ${JSON.stringify(cls.prefix)}`);
349
349
  }
350
- if (!Object.values(AclValues).includes(cls.acl)) {
351
- fail(`needs a static acl — Acl.allowAll, Acl.denyAll or Acl.authenticated. An unstated access rule is a decision nobody made`);
350
+ if (!isAcl(cls.acl)) {
351
+ fail(`needs a static acl — Acl.allowAll, Acl.denyAll, Acl.authenticated or Acl.allowCallers(...). An unstated access rule is a decision nobody made`);
352
352
  }
353
353
  const routes = new Map();
354
354
  const seen = new Map();
@@ -367,7 +367,7 @@ function registerEndpoint(cls, problems) {
367
367
  if (other)
368
368
  fail(`routes ${other} and ${id} both declare ${key}`);
369
369
  seen.set(key, id);
370
- if (r.acl !== undefined && !Object.values(AclValues).includes(r.acl))
370
+ if (r.acl !== undefined && !isAcl(r.acl))
371
371
  fail(`routes.${id}: unknown acl ${JSON.stringify(r.acl)}`);
372
372
  routes.set(id, r);
373
373
  }
package/dist/spec.d.ts CHANGED
@@ -1,7 +1,10 @@
1
- import { Endpoint_Acl, type Spec } from "./_proto/ankka/protocol/v1/discovery_pb.ts";
1
+ import { type MessageInitShape } from "@bufbuild/protobuf";
2
+ import { Endpoint_Acl, type CallerMatcherSchema, type Spec } from "./_proto/ankka/protocol/v1/discovery_pb.ts";
2
3
  import type { Registry } from "./service.ts";
3
- import { Acl } from "./routes.ts";
4
- export declare const PROTOCOL_VERSION = "1.0";
4
+ import type { Acl } from "./routes.ts";
5
+ export declare const PROTOCOL_VERSION = "1.1";
5
6
  export declare const SDK_NAME = "ankka-typescript";
6
7
  export declare function aclToProto(acl: Acl): Endpoint_Acl;
8
+ /** The callers a CALLERS acl names, as discovery carries them; empty for every other rule. */
9
+ export declare function callersToProto(acl: Acl): MessageInitShape<typeof CallerMatcherSchema>[];
7
10
  export declare function renderSpec(registry: Registry): Spec;
package/dist/spec.js CHANGED
@@ -2,22 +2,40 @@
2
2
  import { create } from "@bufbuild/protobuf";
3
3
  import { Endpoint_Acl, SpecSchema } from "./_proto/ankka/protocol/v1/discovery_pb.js";
4
4
  import { kindToProto } from "./kinds.js";
5
- import { Acl } from "./routes.js";
6
5
  import { toJsonSchema } from "./schema.js";
7
6
  import { isCodec } from "./codec.js";
8
7
  import { VERSION } from "./version.js";
9
- export const PROTOCOL_VERSION = "1.0";
8
+ export const PROTOCOL_VERSION = "1.1";
10
9
  export const SDK_NAME = "ankka-typescript";
11
10
  export function aclToProto(acl) {
11
+ if (typeof acl === "object")
12
+ return Endpoint_Acl.CALLERS;
12
13
  switch (acl) {
13
- case Acl.allowAll:
14
+ case "allow-all":
14
15
  return Endpoint_Acl.ALLOW_ALL;
15
- case Acl.denyAll:
16
+ case "deny-all":
16
17
  return Endpoint_Acl.DENY_ALL;
17
- case Acl.authenticated:
18
+ case "authenticated":
18
19
  return Endpoint_Acl.AUTHENTICATED;
19
20
  }
20
21
  }
22
+ /** The callers a CALLERS acl names, as discovery carries them; empty for every other rule. */
23
+ export function callersToProto(acl) {
24
+ if (typeof acl !== "object")
25
+ return [];
26
+ return acl.callers.map((m) => {
27
+ switch (m.kind) {
28
+ case "internet":
29
+ return { kind: { case: "internet", value: {} } };
30
+ case "anyInProject":
31
+ return { kind: { case: "anyInProject", value: {} } };
32
+ case "self":
33
+ return { kind: { case: "self", value: {} } };
34
+ case "service":
35
+ return { kind: { case: "service", value: m.project !== undefined ? { name: m.name, project: m.project } : { name: m.name } } };
36
+ }
37
+ });
38
+ }
21
39
  function handlerInits(handlers) {
22
40
  return [...handlers.values()]
23
41
  .map((h) => ({ name: h.name, readOnly: h.readOnly, streaming: h.streaming }))
@@ -88,13 +106,14 @@ export function renderSpec(registry) {
88
106
  id: e.id,
89
107
  prefix: e.prefix,
90
108
  acl: aclToProto(e.acl),
109
+ allowCallers: callersToProto(e.acl),
91
110
  routes: [...e.routes.entries()].map(([id, r]) => ({
92
111
  id,
93
112
  method: r.method,
94
113
  template: r.template,
95
114
  hasBody: r.body !== undefined,
96
115
  streaming: r.streaming,
97
- ...(r.acl !== undefined ? { acl: aclToProto(r.acl) } : {}),
116
+ ...(r.acl !== undefined ? { acl: aclToProto(r.acl), allowCallers: callersToProto(r.acl) } : {}),
98
117
  })),
99
118
  }));
100
119
  return create(SpecSchema, {
@@ -223,7 +223,11 @@ export class AnkkaTestKit {
223
223
  ...this.#env,
224
224
  })
225
225
  .withExposedPorts(HTTP_PORT, CALLBACK_PORT)
226
- .withWaitStrategy(tc.Wait.forHttp("/_ankka/health", HTTP_PORT).forStatusCode(200))
226
+ // Both ports, not only the health route: it answers as soon as HTTP is bound, which can be
227
+ // before the callback server listens, and Docker's port proxy accepts then resets a
228
+ // connection to a port nothing in the container listens on yet — so a handler's first call
229
+ // after a restart failed UNAVAILABLE. forListeningPorts checks from inside the container.
230
+ .withWaitStrategy(tc.Wait.forAll([tc.Wait.forHttp("/_ankka/health", HTTP_PORT).forStatusCode(200), tc.Wait.forListeningPorts()]))
227
231
  .withStartupTimeout(this.#readyTimeoutMs)
228
232
  .start();
229
233
  this.#sidecar = container;
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.7.1";
1
+ export declare const VERSION = "0.8.0";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Written by scripts/proto.ts from package.json; do not edit. 0.0.0 in the tree, the tag's version in a release.
2
- export const VERSION = "0.7.1";
2
+ export const VERSION = "0.8.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ankka",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "Build services on ankka in TypeScript: entities, views, workflows, agents and endpoints hosted by the ankka sidecar.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",