agntcy-dir 1.1.0 → 1.2.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.
package/README.md CHANGED
@@ -105,6 +105,43 @@ const jwtTransport = await Client.createGRPCTransport(jwtConfig);
105
105
  const jwtClient = new Client(jwtConfig, jwtTransport);
106
106
  ```
107
107
 
108
+ ### OAuth 2.0 for Directory bearer auth
109
+
110
+ The SDK supports OIDC/OAuth for Directory bearer authentication on gRPC:
111
+
112
+ - Interactive login via Authorization Code + PKCE with a loopback callback (`authenticateOAuthPkce()`)
113
+ - Pre-issued access token via `DIRECTORY_CLIENT_AUTH_TOKEN`
114
+
115
+ Interactive PKCE sessions are cached alongside other Directory tooling at `$XDG_CONFIG_HOME/dirctl/auth-token.json` or `~/.config/dirctl/auth-token.json`. Pre-issued tokens from configuration are used directly and are not written to the cache by the constructor.
116
+
117
+ Use this mode when your deployment expects a **Bearer access token** on gRPC (for example via a gateway that validates OIDC tokens). Register your IdP application with a **redirect URI** that matches `DIRECTORY_CLIENT_OIDC_REDIRECT_URI` exactly (for example `http://localhost:8484/callback`). The SDK starts a short-lived HTTP server on loopback to receive the authorization redirect.
118
+
119
+ Some IdPs use **public clients** with PKCE; your IdP may still expect a `client_secret` field in configuration. In that case, use a **random placeholder** from environment variables, not a real secret in source code.
120
+
121
+ **Important:** The default in-repo Envoy authorization stack validates **GitHub** tokens. OIDC access tokens from your IdP only work if your environment’s gateway or auth service is configured to accept them.
122
+
123
+ ```bash
124
+ export DIRECTORY_CLIENT_AUTH_MODE="oidc"
125
+ export DIRECTORY_CLIENT_SERVER_ADDRESS="directory.example.com:443"
126
+ export DIRECTORY_CLIENT_OIDC_ISSUER="https://your-idp-provider.example.com"
127
+ export DIRECTORY_CLIENT_OIDC_CLIENT_ID="your-app-client-id"
128
+ # Optional placeholder for public clients:
129
+ export DIRECTORY_CLIENT_OIDC_CLIENT_SECRET="random-non-secret-string"
130
+ export DIRECTORY_CLIENT_OIDC_REDIRECT_URI="http://localhost:8484/callback"
131
+ # Optional: comma-separated scopes
132
+ # export DIRECTORY_CLIENT_OIDC_SCOPES="openid,profile,email"
133
+ ```
134
+
135
+ ```js
136
+ import { Client } from 'agntcy-dir';
137
+
138
+ // After exporting the variables above (or building a Config with authMode: 'oidc'):
139
+ const client = new Client();
140
+ await client.authenticateOAuthPkce();
141
+ ```
142
+
143
+ For custom transports, call `Client.createGRPCTransport(oidcConfig, { oidcTokenHolder })` with an `OAuthTokenHolder` (exported from this package). The usual path is `new Client(oidcConfig)`, which wires the holder and transport automatically.
144
+
108
145
  ## Getting Started
109
146
 
110
147
  ### Prerequisites
@@ -9,6 +9,8 @@ import type { Message } from '@bufbuild/protobuf';
9
9
  import type { Timestamp } from '@bufbuild/protobuf/wkt';
10
10
  import { Transport } from '@connectrpc/connect';
11
11
 
12
+ export declare type AuthMode = '' | 'x509' | 'jwt' | 'tls' | 'oidc';
13
+
12
14
  /**
13
15
  * Supporting credential type definitions
14
16
  *
@@ -32,6 +34,35 @@ declare type BasicAuthCredentials = Message<"agntcy.dir.store.v1.BasicAuthCreden
32
34
  */
33
35
  declare const BasicAuthCredentialsSchema: GenMessage<BasicAuthCredentials>;
34
36
 
37
+ export declare class CachedToken {
38
+ accessToken: string;
39
+ tokenType: string;
40
+ provider: string;
41
+ issuer: string;
42
+ refreshToken: string;
43
+ expiresAt: Date | undefined;
44
+ user: string;
45
+ userId: string;
46
+ email: string;
47
+ createdAt: Date | undefined;
48
+ constructor(accessToken: string, tokenType?: string, provider?: string, issuer?: string, refreshToken?: string, expiresAt?: Date | undefined, user?: string, userId?: string, email?: string, createdAt?: Date | undefined);
49
+ static fromJson(payload: CachedTokenJson): CachedToken;
50
+ toJson(): Record<string, string>;
51
+ }
52
+
53
+ declare interface CachedTokenJson {
54
+ access_token: string;
55
+ token_type?: string;
56
+ provider?: string;
57
+ issuer?: string;
58
+ refresh_token?: string;
59
+ expires_at?: string;
60
+ user?: string;
61
+ user_id?: string;
62
+ email?: string;
63
+ created_at?: string;
64
+ }
65
+
35
66
  /**
36
67
  * High-level client for interacting with AGNTCY Directory services.
37
68
  *
@@ -62,6 +93,7 @@ export declare class Client {
62
93
  syncClient: Client_2<typeof models_2.store_v1.SyncService>;
63
94
  eventClient: Client_2<typeof models_2.events_v1.EventService>;
64
95
  namingClient: Client_2<typeof models_2.naming_v1.NamingService>;
96
+ private oauthHolder;
65
97
  /**
66
98
  * Initialize the client with the given configuration.
67
99
  *
@@ -87,10 +119,21 @@ export declare class Client {
87
119
  constructor(config?: Config);
88
120
  constructor(config?: Config, grpcTransport?: Transport);
89
121
  private static convertToPEM;
90
- static createGRPCTransport(config: Config): Promise<Transport>;
122
+ private static secureNodeOptions;
123
+ private static createOidcTransport;
124
+ static createGRPCTransport(config: Config, oidcOptions?: {
125
+ oidcTokenHolder: OAuthTokenHolder;
126
+ }): Promise<Transport>;
91
127
  private static createX509Transport;
92
128
  private static createJWTTransport;
93
129
  private static createTLSTransport;
130
+ private cachedTokenFromResponse;
131
+ /**
132
+ * Run browser-based OAuth 2.0 Authorization Code + PKCE login (loopback callback).
133
+ *
134
+ * Requires `authMode: 'oidc'`, `oidcIssuer`, and `oidcClientId`.
135
+ */
136
+ authenticateOAuthPkce(): Promise<void>;
94
137
  /**
95
138
  * Request generator helper function for streaming requests.
96
139
  */
@@ -658,28 +701,50 @@ export declare class Config {
658
701
  static DEFAULT_DIRCTL_PATH: string;
659
702
  static DEFAULT_SPIFFE_ENDPOINT_SOCKET: string;
660
703
  static DEFAULT_AUTH_MODE: string;
704
+ static DEFAULT_AUTH_TOKEN: string;
661
705
  static DEFAULT_JWT_AUDIENCE: string;
662
706
  static DEFAULT_TLS_CA_FILE: string;
663
707
  static DEFAULT_TLS_CERT_FILE: string;
664
708
  static DEFAULT_TLS_KEY_FILE: string;
709
+ static DEFAULT_TLS_SERVER_NAME: string;
710
+ static DEFAULT_TLS_SKIP_VERIFY: boolean;
711
+ static DEFAULT_OIDC_ISSUER: string;
712
+ static DEFAULT_OIDC_CLIENT_ID: string;
713
+ static DEFAULT_OIDC_CLIENT_SECRET: string;
714
+ static DEFAULT_OIDC_REDIRECT_URI: string;
715
+ static DEFAULT_OIDC_CALLBACK_PORT: number;
716
+ static DEFAULT_OIDC_AUTH_TIMEOUT: number;
717
+ static DEFAULT_OIDC_SCOPES: string[];
665
718
  serverAddress: string;
666
719
  dirctlPath: string;
667
720
  spiffeEndpointSocket: string;
668
- authMode: '' | 'x509' | 'jwt' | 'tls';
721
+ authMode: AuthMode;
722
+ authToken: string;
723
+ /** Backward-compatible alias for `authToken`. */
724
+ oidcAccessToken: string;
669
725
  jwtAudience: string;
670
726
  tlsCaFile: string;
671
727
  tlsCertFile: string;
672
728
  tlsKeyFile: string;
729
+ tlsServerName: string;
730
+ tlsSkipVerify: boolean;
731
+ oidcIssuer: string;
732
+ oidcClientId: string;
733
+ oidcClientSecret: string;
734
+ oidcRedirectUri: string;
735
+ oidcCallbackPort: number;
736
+ oidcAuthTimeout: number;
737
+ oidcScopes: string[];
673
738
  /**
674
739
  * Creates a new Config instance.
675
740
  *
676
741
  * @param serverAddress - The server address to connect to. Defaults to '127.0.0.1:8888'
677
742
  * @param dirctlPath - Path to the dirctl executable. Defaults to 'dirctl'
678
743
  * @param spiffeEndpointSocket - Path to the spire server socket. Defaults to empty string.
679
- * @param authMode - Authentication mode: '' for insecure, 'x509', 'jwt' or 'tls'. Defaults to ''
744
+ * @param authMode - Authentication mode: '' for insecure, 'x509', 'jwt', 'tls', or 'oidc'. Defaults to ''
680
745
  * @param jwtAudience - JWT audience for JWT authentication. Required when authMode is 'jwt'
681
746
  */
682
- constructor(serverAddress?: string, dirctlPath?: string, spiffeEndpointSocket?: string, authMode?: '' | 'x509' | 'jwt' | 'tls', jwtAudience?: string, tlsCaFile?: string, tlsCertFile?: string, tlsKeyFile?: string);
747
+ constructor(serverAddress?: string, dirctlPath?: string, spiffeEndpointSocket?: string, authMode?: AuthMode, jwtAudience?: string, tlsCaFile?: string, tlsCertFile?: string, tlsKeyFile?: string, authToken?: string, tlsServerName?: string, tlsSkipVerify?: boolean, oidcIssuer?: string, oidcClientId?: string, oidcClientSecret?: string, oidcRedirectUri?: string, oidcCallbackPort?: number, oidcAuthTimeout?: number, oidcScopes?: string[] | undefined, oidcAccessToken?: string | undefined);
683
748
  /**
684
749
  * Load configuration from environment variables.
685
750
  *
@@ -793,6 +858,58 @@ declare type CreateSyncResponse = Message<"agntcy.dir.store.v1.CreateSyncRespons
793
858
  */
794
859
  declare const CreateSyncResponseSchema: GenMessage<CreateSyncResponse>;
795
860
 
861
+ /**
862
+ * @generated from message agntcy.dir.store.v1.DeleteReferrerRequest
863
+ */
864
+ declare type DeleteReferrerRequest = Message<"agntcy.dir.store.v1.DeleteReferrerRequest"> & {
865
+ /**
866
+ * The record the referrer(s) are referring to.
867
+ *
868
+ * @generated from field: agntcy.dir.core.v1.RecordRef record = 1;
869
+ */
870
+ record?: RecordRef;
871
+
872
+ /**
873
+ * The CID of the referrer to delete.
874
+ * If set, delete the referrer by CID.
875
+ *
876
+ * @generated from field: optional agntcy.dir.core.v1.ReferrerRef referrer_ref = 2;
877
+ */
878
+ referrerRef?: ReferrerRef;
879
+
880
+ /**
881
+ * The referrer type of the referrers to delete.
882
+ * If set, delete the referrers with given type.
883
+ *
884
+ * @generated from field: optional string referrer_type = 3;
885
+ */
886
+ referrerType?: string;
887
+ };
888
+
889
+ /**
890
+ * Describes the message agntcy.dir.store.v1.DeleteReferrerRequest.
891
+ * Use `create(DeleteReferrerRequestSchema)` to create a new message.
892
+ */
893
+ declare const DeleteReferrerRequestSchema: GenMessage<DeleteReferrerRequest>;
894
+
895
+ /**
896
+ * @generated from message agntcy.dir.store.v1.DeleteReferrerResponse
897
+ */
898
+ declare type DeleteReferrerResponse = Message<"agntcy.dir.store.v1.DeleteReferrerResponse"> & {
899
+ /**
900
+ * The CID(s) of the deleted referrers.
901
+ *
902
+ * @generated from field: repeated agntcy.dir.core.v1.ReferrerRef referrer_refs = 1;
903
+ */
904
+ referrerRefs: ReferrerRef[];
905
+ };
906
+
907
+ /**
908
+ * Describes the message agntcy.dir.store.v1.DeleteReferrerResponse.
909
+ * Use `create(DeleteReferrerResponseSchema)` to create a new message.
910
+ */
911
+ declare const DeleteReferrerResponseSchema: GenMessage<DeleteReferrerResponse>;
912
+
796
913
  /**
797
914
  * DeleteSyncRequest specifies which synchronization to delete.
798
915
  *
@@ -1696,6 +1813,17 @@ declare const NamingService: GenService<{
1696
1813
  },
1697
1814
  }>;
1698
1815
 
1816
+ export declare class OAuthPkceError extends Error {
1817
+ constructor(message: string);
1818
+ }
1819
+
1820
+ export declare class OAuthTokenHolder {
1821
+ private accessToken;
1822
+ setTokens(accessToken: string): void;
1823
+ updateFromTokenResponse(payload: Record<string, unknown>): void;
1824
+ getAccessToken(): string;
1825
+ }
1826
+
1699
1827
  /**
1700
1828
  * @generated from message agntcy.dir.routing.v1.Peer
1701
1829
  */
@@ -1952,6 +2080,13 @@ declare type PullReferrerRequest = Message<"agntcy.dir.store.v1.PullReferrerRequ
1952
2080
  * @generated from field: optional string referrer_type = 2;
1953
2081
  */
1954
2082
  referrerType?: string;
2083
+
2084
+ /**
2085
+ * If set, return the given referrer.
2086
+ *
2087
+ * @generated from field: optional agntcy.dir.core.v1.ReferrerRef referrer_ref = 3;
2088
+ */
2089
+ referrerRef?: ReferrerRef;
1955
2090
  };
1956
2091
 
1957
2092
  /**
@@ -2448,6 +2583,13 @@ declare type RecordReferrer = Message<"agntcy.dir.core.v1.RecordReferrer"> & {
2448
2583
  * @generated from field: google.protobuf.Struct data = 5;
2449
2584
  */
2450
2585
  data?: JsonObject;
2586
+
2587
+ /**
2588
+ * The CID of the referrer.
2589
+ *
2590
+ * @generated from field: agntcy.dir.core.v1.ReferrerRef referrer_ref = 6;
2591
+ */
2592
+ referrerRef?: ReferrerRef;
2451
2593
  };
2452
2594
 
2453
2595
  /**
@@ -3425,6 +3567,10 @@ export declare namespace store_v1 {
3425
3567
  PullReferrerRequestSchema,
3426
3568
  PullReferrerResponse,
3427
3569
  PullReferrerResponseSchema,
3570
+ DeleteReferrerRequest,
3571
+ DeleteReferrerRequestSchema,
3572
+ DeleteReferrerResponse,
3573
+ DeleteReferrerResponseSchema,
3428
3574
  StoreService,
3429
3575
  file_agntcy_dir_store_v1_sync_service,
3430
3576
  CreateSyncRequest,
@@ -3535,6 +3681,16 @@ declare const StoreService: GenService<{
3535
3681
  input: typeof PullReferrerRequestSchema;
3536
3682
  output: typeof PullReferrerResponseSchema;
3537
3683
  },
3684
+ /**
3685
+ * DeleteReferrer performs delete operation for record referrers.
3686
+ *
3687
+ * @generated from rpc agntcy.dir.store.v1.StoreService.DeleteReferrer
3688
+ */
3689
+ deleteReferrer: {
3690
+ methodKind: "bidi_streaming";
3691
+ input: typeof DeleteReferrerRequestSchema;
3692
+ output: typeof DeleteReferrerResponseSchema;
3693
+ },
3538
3694
  }>;
3539
3695
 
3540
3696
  /**
@@ -3668,6 +3824,19 @@ declare enum SyncStatus {
3668
3824
  */
3669
3825
  declare const SyncStatusSchema: GenEnum<SyncStatus>;
3670
3826
 
3827
+ export declare const TOKEN_CACHE_FILE = "auth-token.json";
3828
+
3829
+ export declare class TokenCache {
3830
+ readonly cacheDir: string;
3831
+ constructor(cacheDir?: string);
3832
+ getCachePath(): string;
3833
+ load(): CachedToken | undefined;
3834
+ save(token: CachedToken): void;
3835
+ clear(): void;
3836
+ isValid(token: CachedToken | undefined): boolean;
3837
+ getValidToken(): CachedToken | undefined;
3838
+ }
3839
+
3671
3840
  /**
3672
3841
  * @generated from message agntcy.dir.routing.v1.UnpublishRequest
3673
3842
  */