@enterprisestandard/react 0.0.5-beta.20260115.2 → 0.0.5-beta.20260115.4
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/dist/index.d.ts +2573 -41
- package/dist/index.js +3732 -144
- package/dist/index.js.map +1 -0
- package/package.json +3 -1
- package/dist/group-store.d.ts +0 -164
- package/dist/group-store.d.ts.map +0 -1
- package/dist/group-store.js +0 -127
- package/dist/iam.d.ts +0 -206
- package/dist/iam.d.ts.map +0 -1
- package/dist/iam.js +0 -680
- package/dist/index.d.ts.map +0 -1
- package/dist/session-store.d.ts +0 -179
- package/dist/session-store.d.ts.map +0 -1
- package/dist/session-store.js +0 -105
- package/dist/sso-server.d.ts +0 -13
- package/dist/sso-server.d.ts.map +0 -1
- package/dist/sso-server.js +0 -46
- package/dist/sso.d.ts +0 -104
- package/dist/sso.d.ts.map +0 -1
- package/dist/sso.js +0 -820
- package/dist/tenant-server.d.ts +0 -8
- package/dist/tenant-server.d.ts.map +0 -1
- package/dist/tenant-server.js +0 -6
- package/dist/tenant.d.ts +0 -280
- package/dist/tenant.d.ts.map +0 -1
- package/dist/tenant.js +0 -324
- package/dist/types/base-user.d.ts +0 -27
- package/dist/types/base-user.d.ts.map +0 -1
- package/dist/types/base-user.js +0 -1
- package/dist/types/enterprise-user.d.ts +0 -158
- package/dist/types/enterprise-user.d.ts.map +0 -1
- package/dist/types/enterprise-user.js +0 -1
- package/dist/types/oidc-schema.d.ts +0 -86
- package/dist/types/oidc-schema.d.ts.map +0 -1
- package/dist/types/oidc-schema.js +0 -328
- package/dist/types/scim-schema.d.ts +0 -419
- package/dist/types/scim-schema.d.ts.map +0 -1
- package/dist/types/scim-schema.js +0 -519
- package/dist/types/standard-schema.d.ts +0 -56
- package/dist/types/standard-schema.d.ts.map +0 -1
- package/dist/types/standard-schema.js +0 -1
- package/dist/types/user.d.ts +0 -41
- package/dist/types/user.d.ts.map +0 -1
- package/dist/types/user.js +0 -1
- package/dist/types/workload-schema.d.ts +0 -106
- package/dist/types/workload-schema.d.ts.map +0 -1
- package/dist/types/workload-schema.js +0 -208
- package/dist/ui/sign-in-loading.d.ts +0 -5
- package/dist/ui/sign-in-loading.d.ts.map +0 -1
- package/dist/ui/sign-in-loading.js +0 -8
- package/dist/ui/signed-in.d.ts +0 -3
- package/dist/ui/signed-in.d.ts.map +0 -1
- package/dist/ui/signed-in.js +0 -8
- package/dist/ui/signed-out.d.ts +0 -3
- package/dist/ui/signed-out.d.ts.map +0 -1
- package/dist/ui/signed-out.js +0 -8
- package/dist/ui/sso-provider.d.ts +0 -35
- package/dist/ui/sso-provider.d.ts.map +0 -1
- package/dist/ui/sso-provider.js +0 -275
- package/dist/user-store.d.ts +0 -161
- package/dist/user-store.d.ts.map +0 -1
- package/dist/user-store.js +0 -114
- package/dist/utils.d.ts +0 -9
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -23
- package/dist/vault.d.ts +0 -18
- package/dist/vault.d.ts.map +0 -1
- package/dist/vault.js +0 -22
- package/dist/workload-server.d.ts +0 -127
- package/dist/workload-server.d.ts.map +0 -1
- package/dist/workload-server.js +0 -167
- package/dist/workload-token-store.d.ts +0 -187
- package/dist/workload-token-store.d.ts.map +0 -1
- package/dist/workload-token-store.js +0 -95
- package/dist/workload.d.ts +0 -227
- package/dist/workload.d.ts.map +0 -1
- package/dist/workload.js +0 -691
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import type { EnterpriseStandard } from '.';
|
|
2
|
-
import type { TokenValidationResult } from './types/workload-schema';
|
|
3
|
-
import type { WorkloadIdentity } from './workload';
|
|
4
|
-
/**
|
|
5
|
-
* Get the workload identity from an incoming request.
|
|
6
|
-
* Returns undefined if no valid workload token is present.
|
|
7
|
-
*
|
|
8
|
-
* @param request - Request with Authorization header
|
|
9
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
10
|
-
* @returns WorkloadIdentity or undefined
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* import { getWorkload } from '@enterprisestandard/react';
|
|
15
|
-
*
|
|
16
|
-
* export async function handler(request: Request) {
|
|
17
|
-
* const workload = await getWorkload(request);
|
|
18
|
-
*
|
|
19
|
-
* if (!workload) {
|
|
20
|
-
* return new Response('Unauthorized', { status: 401 });
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* console.log('Request from workload:', workload.workload_id);
|
|
24
|
-
* // ... process authenticated request
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export declare function getWorkload(request: Request, es?: EnterpriseStandard): Promise<WorkloadIdentity | undefined>;
|
|
29
|
-
/**
|
|
30
|
-
* Get an access token for the configured workload identity.
|
|
31
|
-
*
|
|
32
|
-
* @param scope - Optional OAuth2 scopes (space-delimited)
|
|
33
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
34
|
-
* @returns Access token string
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```typescript
|
|
38
|
-
* import { getWorkloadToken } from '@enterprisestandard/react/server';
|
|
39
|
-
*
|
|
40
|
-
* // Get token for API calls
|
|
41
|
-
* const token = await getWorkloadToken('api:read api:write');
|
|
42
|
-
*
|
|
43
|
-
* // Use in outbound requests
|
|
44
|
-
* const response = await fetch('https://api.example.com/data', {
|
|
45
|
-
* headers: { 'Authorization': `Bearer ${token}` },
|
|
46
|
-
* });
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export declare function getWorkloadToken(scope?: string, es?: EnterpriseStandard): Promise<string>;
|
|
50
|
-
/**
|
|
51
|
-
* Validate a workload token from an incoming request.
|
|
52
|
-
*
|
|
53
|
-
* @param request - Request with Authorization header
|
|
54
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
55
|
-
* @returns Token validation result
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```typescript
|
|
59
|
-
* import { validateWorkloadToken } from '@enterprisestandard/react/server';
|
|
60
|
-
*
|
|
61
|
-
* export async function handler(request: Request) {
|
|
62
|
-
* const result = await validateWorkloadToken(request);
|
|
63
|
-
*
|
|
64
|
-
* if (!result.valid) {
|
|
65
|
-
* return new Response(
|
|
66
|
-
* JSON.stringify({ error: result.error }),
|
|
67
|
-
* { status: 401 }
|
|
68
|
-
* );
|
|
69
|
-
* }
|
|
70
|
-
*
|
|
71
|
-
* const workloadId = result.claims?.iss;
|
|
72
|
-
* // ... process authenticated request
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
export declare function validateWorkloadToken(request: Request, es?: EnterpriseStandard): Promise<TokenValidationResult>;
|
|
77
|
-
/**
|
|
78
|
-
* Revoke a workload access token.
|
|
79
|
-
*
|
|
80
|
-
* @param token - The access token to revoke
|
|
81
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```typescript
|
|
85
|
-
* import { revokeWorkloadToken } from '@enterprisestandard/react/server';
|
|
86
|
-
*
|
|
87
|
-
* // Revoke token when workload is decommissioned
|
|
88
|
-
* await revokeWorkloadToken(accessToken);
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
export declare function revokeWorkloadToken(token: string, es?: EnterpriseStandard): Promise<void>;
|
|
92
|
-
/**
|
|
93
|
-
* Framework-agnostic handler for workload authentication routes.
|
|
94
|
-
*
|
|
95
|
-
* The handler reads configuration (handler URLs, validation) directly from the
|
|
96
|
-
* EnterpriseStandard instance, so no config parameter is needed.
|
|
97
|
-
*
|
|
98
|
-
* @param request - Incoming request
|
|
99
|
-
* @param config - Optional ESConfig to specify which EnterpriseStandard instance to use
|
|
100
|
-
* @returns Response
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```typescript
|
|
104
|
-
* import { workloadHandler } from '@enterprisestandard/react/server';
|
|
105
|
-
*
|
|
106
|
-
* // TanStack Start example
|
|
107
|
-
* export const Route = createFileRoute('/api/workload/$')({
|
|
108
|
-
* server: {
|
|
109
|
-
* handlers: ({ createHandlers }) =>
|
|
110
|
-
* createHandlers({
|
|
111
|
-
* GET: {
|
|
112
|
-
* handler: async ({ request }) => {
|
|
113
|
-
* return workloadHandler(request);
|
|
114
|
-
* },
|
|
115
|
-
* },
|
|
116
|
-
* POST: {
|
|
117
|
-
* handler: async ({ request }) => {
|
|
118
|
-
* return workloadHandler(request);
|
|
119
|
-
* },
|
|
120
|
-
* },
|
|
121
|
-
* }),
|
|
122
|
-
* },
|
|
123
|
-
* });
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
export declare function workloadHandler(request: Request, es?: EnterpriseStandard): Promise<Response>;
|
|
127
|
-
//# sourceMappingURL=workload-server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workload-server.d.ts","sourceRoot":"","sources":["../src/workload-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,GAAG,CAAC;AAC5C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAcnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAMlH;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAarH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAIlG"}
|
package/dist/workload-server.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { getES } from './utils';
|
|
2
|
-
/**
|
|
3
|
-
* Returns a 503 response indicating that the SSO is unavailable
|
|
4
|
-
*/
|
|
5
|
-
function unavailable(error) {
|
|
6
|
-
error = error ?? 'Workload authentication unavailable';
|
|
7
|
-
new Response(JSON.stringify({ error }), {
|
|
8
|
-
status: 503,
|
|
9
|
-
statusText: error,
|
|
10
|
-
headers: { 'Content-Type': 'application/json' },
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Get the workload identity from an incoming request.
|
|
15
|
-
* Returns undefined if no valid workload token is present.
|
|
16
|
-
*
|
|
17
|
-
* @param request - Request with Authorization header
|
|
18
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
19
|
-
* @returns WorkloadIdentity or undefined
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* import { getWorkload } from '@enterprisestandard/react';
|
|
24
|
-
*
|
|
25
|
-
* export async function handler(request: Request) {
|
|
26
|
-
* const workload = await getWorkload(request);
|
|
27
|
-
*
|
|
28
|
-
* if (!workload) {
|
|
29
|
-
* return new Response('Unauthorized', { status: 401 });
|
|
30
|
-
* }
|
|
31
|
-
*
|
|
32
|
-
* console.log('Request from workload:', workload.workload_id);
|
|
33
|
-
* // ... process authenticated request
|
|
34
|
-
* }
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
export async function getWorkload(request, es) {
|
|
38
|
-
const workloadAuth = getES(es)?.workload;
|
|
39
|
-
if (!workloadAuth) {
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
return workloadAuth.getWorkload(request);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Get an access token for the configured workload identity.
|
|
46
|
-
*
|
|
47
|
-
* @param scope - Optional OAuth2 scopes (space-delimited)
|
|
48
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
49
|
-
* @returns Access token string
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* import { getWorkloadToken } from '@enterprisestandard/react/server';
|
|
54
|
-
*
|
|
55
|
-
* // Get token for API calls
|
|
56
|
-
* const token = await getWorkloadToken('api:read api:write');
|
|
57
|
-
*
|
|
58
|
-
* // Use in outbound requests
|
|
59
|
-
* const response = await fetch('https://api.example.com/data', {
|
|
60
|
-
* headers: { 'Authorization': `Bearer ${token}` },
|
|
61
|
-
* });
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
export async function getWorkloadToken(scope, es) {
|
|
65
|
-
const workloadAuth = getES(es)?.workload;
|
|
66
|
-
if (!workloadAuth)
|
|
67
|
-
throw unavailable();
|
|
68
|
-
return workloadAuth.getToken(scope);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Validate a workload token from an incoming request.
|
|
72
|
-
*
|
|
73
|
-
* @param request - Request with Authorization header
|
|
74
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
75
|
-
* @returns Token validation result
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* import { validateWorkloadToken } from '@enterprisestandard/react/server';
|
|
80
|
-
*
|
|
81
|
-
* export async function handler(request: Request) {
|
|
82
|
-
* const result = await validateWorkloadToken(request);
|
|
83
|
-
*
|
|
84
|
-
* if (!result.valid) {
|
|
85
|
-
* return new Response(
|
|
86
|
-
* JSON.stringify({ error: result.error }),
|
|
87
|
-
* { status: 401 }
|
|
88
|
-
* );
|
|
89
|
-
* }
|
|
90
|
-
*
|
|
91
|
-
* const workloadId = result.claims?.iss;
|
|
92
|
-
* // ... process authenticated request
|
|
93
|
-
* }
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
export async function validateWorkloadToken(request, es) {
|
|
97
|
-
const workloadAuth = getES(es)?.workload;
|
|
98
|
-
if (!workloadAuth) {
|
|
99
|
-
return { valid: false, error: 'Workload authentication unavailable' };
|
|
100
|
-
}
|
|
101
|
-
const authHeader = request.headers.get('Authorization');
|
|
102
|
-
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
103
|
-
return { valid: false, error: 'Missing or invalid Authorization header' };
|
|
104
|
-
}
|
|
105
|
-
const token = authHeader.substring(7);
|
|
106
|
-
return workloadAuth.validateToken(token);
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Revoke a workload access token.
|
|
110
|
-
*
|
|
111
|
-
* @param token - The access token to revoke
|
|
112
|
-
* @param config - Optional EnterpriseStandard configuration
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```typescript
|
|
116
|
-
* import { revokeWorkloadToken } from '@enterprisestandard/react/server';
|
|
117
|
-
*
|
|
118
|
-
* // Revoke token when workload is decommissioned
|
|
119
|
-
* await revokeWorkloadToken(accessToken);
|
|
120
|
-
* ```
|
|
121
|
-
*/
|
|
122
|
-
export async function revokeWorkloadToken(token, es) {
|
|
123
|
-
const workloadAuth = getES(es)?.workload;
|
|
124
|
-
if (!workloadAuth)
|
|
125
|
-
throw unavailable();
|
|
126
|
-
return workloadAuth.revokeToken(token);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Framework-agnostic handler for workload authentication routes.
|
|
130
|
-
*
|
|
131
|
-
* The handler reads configuration (handler URLs, validation) directly from the
|
|
132
|
-
* EnterpriseStandard instance, so no config parameter is needed.
|
|
133
|
-
*
|
|
134
|
-
* @param request - Incoming request
|
|
135
|
-
* @param config - Optional ESConfig to specify which EnterpriseStandard instance to use
|
|
136
|
-
* @returns Response
|
|
137
|
-
*
|
|
138
|
-
* @example
|
|
139
|
-
* ```typescript
|
|
140
|
-
* import { workloadHandler } from '@enterprisestandard/react/server';
|
|
141
|
-
*
|
|
142
|
-
* // TanStack Start example
|
|
143
|
-
* export const Route = createFileRoute('/api/workload/$')({
|
|
144
|
-
* server: {
|
|
145
|
-
* handlers: ({ createHandlers }) =>
|
|
146
|
-
* createHandlers({
|
|
147
|
-
* GET: {
|
|
148
|
-
* handler: async ({ request }) => {
|
|
149
|
-
* return workloadHandler(request);
|
|
150
|
-
* },
|
|
151
|
-
* },
|
|
152
|
-
* POST: {
|
|
153
|
-
* handler: async ({ request }) => {
|
|
154
|
-
* return workloadHandler(request);
|
|
155
|
-
* },
|
|
156
|
-
* },
|
|
157
|
-
* }),
|
|
158
|
-
* },
|
|
159
|
-
* });
|
|
160
|
-
* ```
|
|
161
|
-
*/
|
|
162
|
-
export async function workloadHandler(request, es) {
|
|
163
|
-
const workloadAuth = getES(es)?.workload;
|
|
164
|
-
if (!workloadAuth)
|
|
165
|
-
throw unavailable();
|
|
166
|
-
return workloadAuth.handler(request);
|
|
167
|
-
}
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token caching for workload identity authentication.
|
|
3
|
-
*
|
|
4
|
-
* Token stores are optional but recommended for performance - they enable:
|
|
5
|
-
* - Token caching to avoid repeated token acquisition
|
|
6
|
-
* - Automatic token refresh before expiration
|
|
7
|
-
* - Reduced load on authorization servers
|
|
8
|
-
*
|
|
9
|
-
* ## Token Caching Strategy
|
|
10
|
-
*
|
|
11
|
-
* Unlike session stores for user authentication, workload token stores cache
|
|
12
|
-
* short-lived access tokens (typically 5 minutes) for service-to-service calls.
|
|
13
|
-
*
|
|
14
|
-
* **Default Behavior:**
|
|
15
|
-
* - Tokens cached with 5-minute TTL
|
|
16
|
-
* - Auto-refresh 60 seconds before expiration
|
|
17
|
-
* - Expired tokens automatically removed
|
|
18
|
-
*
|
|
19
|
-
* ## Performance Characteristics
|
|
20
|
-
*
|
|
21
|
-
* | Backend | Lookup Time | Use Case |
|
|
22
|
-
* |--------------|-------------|----------------------------|
|
|
23
|
-
* | InMemory | <0.00005ms | Single-server deployments |
|
|
24
|
-
* | Redis | 1-2ms | Multi-server deployments |
|
|
25
|
-
* | Database | 5-20ms | Persistent token storage |
|
|
26
|
-
*
|
|
27
|
-
* ## Example Usage
|
|
28
|
-
*
|
|
29
|
-
* ```typescript
|
|
30
|
-
* import { workload, InMemoryWorkloadTokenStore } from '@enterprisestandard/react/server';
|
|
31
|
-
*
|
|
32
|
-
* // With token caching
|
|
33
|
-
* const workloadAuth = workload({
|
|
34
|
-
* // ... other config
|
|
35
|
-
* token_store: new InMemoryWorkloadTokenStore(),
|
|
36
|
-
* auto_refresh: true, // Refresh before expiry
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* // Without token caching (fetch new token each time)
|
|
40
|
-
* const workloadAuth = workload({
|
|
41
|
-
* // ... config without token_store
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
/**
|
|
46
|
-
* Cached workload token data.
|
|
47
|
-
*
|
|
48
|
-
* @template TExtended - Type-safe custom data that consumers can add to cached tokens
|
|
49
|
-
*/
|
|
50
|
-
export type CachedWorkloadToken<TExtended = object> = {
|
|
51
|
-
/**
|
|
52
|
-
* Workload identifier (typically SPIFFE ID).
|
|
53
|
-
* Used as the primary key for token lookup.
|
|
54
|
-
*/
|
|
55
|
-
workload_id: string;
|
|
56
|
-
/**
|
|
57
|
-
* OAuth2 access token (Bearer token)
|
|
58
|
-
*/
|
|
59
|
-
access_token: string;
|
|
60
|
-
/**
|
|
61
|
-
* Token type (always "Bearer" for OAuth2)
|
|
62
|
-
*/
|
|
63
|
-
token_type: string;
|
|
64
|
-
/**
|
|
65
|
-
* OAuth2 scopes granted for this token
|
|
66
|
-
*/
|
|
67
|
-
scope?: string;
|
|
68
|
-
/**
|
|
69
|
-
* Timestamp when the token expires.
|
|
70
|
-
* Used for automatic cleanup and refresh logic.
|
|
71
|
-
*/
|
|
72
|
-
expires_at: Date;
|
|
73
|
-
/**
|
|
74
|
-
* Timestamp when the token was created/cached.
|
|
75
|
-
*/
|
|
76
|
-
created_at: Date;
|
|
77
|
-
/**
|
|
78
|
-
* Optional refresh token (rarely used for workload identities)
|
|
79
|
-
*/
|
|
80
|
-
refresh_token?: string;
|
|
81
|
-
} & TExtended;
|
|
82
|
-
/**
|
|
83
|
-
* Abstract interface for workload token storage backends.
|
|
84
|
-
*
|
|
85
|
-
* Consumers can implement this interface to use different storage backends:
|
|
86
|
-
* - Redis (recommended for multi-server deployments)
|
|
87
|
-
* - Database (PostgreSQL, MySQL, etc. for persistence)
|
|
88
|
-
* - Distributed cache (Memcached, etc.)
|
|
89
|
-
* - Custom solutions
|
|
90
|
-
*
|
|
91
|
-
* @template TExtended - Type-safe custom data that consumers can add to cached tokens
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* // Custom token cache data
|
|
96
|
-
* type MyTokenData = {
|
|
97
|
-
* environment: string;
|
|
98
|
-
* region: string;
|
|
99
|
-
* };
|
|
100
|
-
*
|
|
101
|
-
* // Implement custom store with Redis
|
|
102
|
-
* class RedisWorkloadTokenStore implements WorkloadTokenStore<MyTokenData> {
|
|
103
|
-
* async set(token: CachedWorkloadToken<MyTokenData>): Promise<void> {
|
|
104
|
-
* const ttl = Math.floor((token.expires_at.getTime() - Date.now()) / 1000);
|
|
105
|
-
* await redis.setex(
|
|
106
|
-
* `workload:token:${token.workload_id}`,
|
|
107
|
-
* ttl,
|
|
108
|
-
* JSON.stringify(token)
|
|
109
|
-
* );
|
|
110
|
-
* }
|
|
111
|
-
*
|
|
112
|
-
* async get(workload_id: string): Promise<CachedWorkloadToken<MyTokenData> | null> {
|
|
113
|
-
* const data = await redis.get(`workload:token:${workload_id}`);
|
|
114
|
-
* if (!data) return null;
|
|
115
|
-
* const token = JSON.parse(data);
|
|
116
|
-
* // Convert date strings back to Date objects
|
|
117
|
-
* token.expires_at = new Date(token.expires_at);
|
|
118
|
-
* token.created_at = new Date(token.created_at);
|
|
119
|
-
* return token;
|
|
120
|
-
* }
|
|
121
|
-
*
|
|
122
|
-
* // ... other methods
|
|
123
|
-
* }
|
|
124
|
-
* ```
|
|
125
|
-
*/
|
|
126
|
-
export interface WorkloadTokenStore<TExtended = object> {
|
|
127
|
-
/**
|
|
128
|
-
* Store or update a workload token in the cache.
|
|
129
|
-
*
|
|
130
|
-
* @param token - The token data to cache
|
|
131
|
-
*/
|
|
132
|
-
set(token: CachedWorkloadToken<TExtended>): Promise<void>;
|
|
133
|
-
/**
|
|
134
|
-
* Retrieve a cached token by workload ID.
|
|
135
|
-
*
|
|
136
|
-
* @param workload_id - The workload identifier (e.g., SPIFFE ID)
|
|
137
|
-
* @returns The cached token if found and not expired, null otherwise
|
|
138
|
-
*/
|
|
139
|
-
get(workload_id: string): Promise<CachedWorkloadToken<TExtended> | null>;
|
|
140
|
-
/**
|
|
141
|
-
* Delete a cached token by workload ID.
|
|
142
|
-
*
|
|
143
|
-
* Used when explicitly revoking tokens or clearing cache.
|
|
144
|
-
*
|
|
145
|
-
* @param workload_id - The workload identifier to remove
|
|
146
|
-
*/
|
|
147
|
-
delete(workload_id: string): Promise<void>;
|
|
148
|
-
/**
|
|
149
|
-
* Check if a valid (non-expired) token exists for a workload.
|
|
150
|
-
*
|
|
151
|
-
* @param workload_id - The workload identifier to check
|
|
152
|
-
* @returns true if a valid token exists, false otherwise
|
|
153
|
-
*/
|
|
154
|
-
isValid(workload_id: string): Promise<boolean>;
|
|
155
|
-
/**
|
|
156
|
-
* Remove all expired tokens from the cache.
|
|
157
|
-
*
|
|
158
|
-
* Should be called periodically to prevent memory leaks.
|
|
159
|
-
*/
|
|
160
|
-
cleanup(): Promise<void>;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* In-memory workload token store implementation using Maps.
|
|
164
|
-
*
|
|
165
|
-
* Suitable for:
|
|
166
|
-
* - Development and testing
|
|
167
|
-
* - Single-server deployments
|
|
168
|
-
* - Applications without high availability requirements
|
|
169
|
-
*
|
|
170
|
-
* NOT suitable for:
|
|
171
|
-
* - Multi-server deployments (tokens not shared across instances)
|
|
172
|
-
* - High availability scenarios (tokens lost on restart)
|
|
173
|
-
* - Production applications with distributed architecture
|
|
174
|
-
*
|
|
175
|
-
* For production multi-server deployments, implement WorkloadTokenStore with Redis.
|
|
176
|
-
*
|
|
177
|
-
* @template TExtended - Type-safe custom data that consumers can add to cached tokens
|
|
178
|
-
*/
|
|
179
|
-
export declare class InMemoryWorkloadTokenStore<TExtended = object> implements WorkloadTokenStore<TExtended> {
|
|
180
|
-
private tokens;
|
|
181
|
-
set(token: CachedWorkloadToken<TExtended>): Promise<void>;
|
|
182
|
-
get(workload_id: string): Promise<CachedWorkloadToken<TExtended> | null>;
|
|
183
|
-
delete(workload_id: string): Promise<void>;
|
|
184
|
-
isValid(workload_id: string): Promise<boolean>;
|
|
185
|
-
cleanup(): Promise<void>;
|
|
186
|
-
}
|
|
187
|
-
//# sourceMappingURL=workload-token-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workload-token-store.d.ts","sourceRoot":"","sources":["../src/workload-token-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAAC,SAAS,GAAG,MAAM,IAAI;IACpD;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,UAAU,EAAE,IAAI,CAAC;IAEjB;;OAEG;IACH,UAAU,EAAE,IAAI,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,SAAS,CAAC;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,WAAW,kBAAkB,CAAC,SAAS,GAAG,MAAM;IACpD;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;;OAKG;IACH,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzE;;;;;;OAMG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C;;;;;OAKG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/C;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,0BAA0B,CAAC,SAAS,GAAG,MAAM,CAAE,YAAW,kBAAkB,CAAC,SAAS,CAAC;IAClG,OAAO,CAAC,MAAM,CAAqD;IAE7D,GAAG,CAAC,KAAK,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAaxE,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ/B"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Token caching for workload identity authentication.
|
|
3
|
-
*
|
|
4
|
-
* Token stores are optional but recommended for performance - they enable:
|
|
5
|
-
* - Token caching to avoid repeated token acquisition
|
|
6
|
-
* - Automatic token refresh before expiration
|
|
7
|
-
* - Reduced load on authorization servers
|
|
8
|
-
*
|
|
9
|
-
* ## Token Caching Strategy
|
|
10
|
-
*
|
|
11
|
-
* Unlike session stores for user authentication, workload token stores cache
|
|
12
|
-
* short-lived access tokens (typically 5 minutes) for service-to-service calls.
|
|
13
|
-
*
|
|
14
|
-
* **Default Behavior:**
|
|
15
|
-
* - Tokens cached with 5-minute TTL
|
|
16
|
-
* - Auto-refresh 60 seconds before expiration
|
|
17
|
-
* - Expired tokens automatically removed
|
|
18
|
-
*
|
|
19
|
-
* ## Performance Characteristics
|
|
20
|
-
*
|
|
21
|
-
* | Backend | Lookup Time | Use Case |
|
|
22
|
-
* |--------------|-------------|----------------------------|
|
|
23
|
-
* | InMemory | <0.00005ms | Single-server deployments |
|
|
24
|
-
* | Redis | 1-2ms | Multi-server deployments |
|
|
25
|
-
* | Database | 5-20ms | Persistent token storage |
|
|
26
|
-
*
|
|
27
|
-
* ## Example Usage
|
|
28
|
-
*
|
|
29
|
-
* ```typescript
|
|
30
|
-
* import { workload, InMemoryWorkloadTokenStore } from '@enterprisestandard/react/server';
|
|
31
|
-
*
|
|
32
|
-
* // With token caching
|
|
33
|
-
* const workloadAuth = workload({
|
|
34
|
-
* // ... other config
|
|
35
|
-
* token_store: new InMemoryWorkloadTokenStore(),
|
|
36
|
-
* auto_refresh: true, // Refresh before expiry
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* // Without token caching (fetch new token each time)
|
|
40
|
-
* const workloadAuth = workload({
|
|
41
|
-
* // ... config without token_store
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
/**
|
|
46
|
-
* In-memory workload token store implementation using Maps.
|
|
47
|
-
*
|
|
48
|
-
* Suitable for:
|
|
49
|
-
* - Development and testing
|
|
50
|
-
* - Single-server deployments
|
|
51
|
-
* - Applications without high availability requirements
|
|
52
|
-
*
|
|
53
|
-
* NOT suitable for:
|
|
54
|
-
* - Multi-server deployments (tokens not shared across instances)
|
|
55
|
-
* - High availability scenarios (tokens lost on restart)
|
|
56
|
-
* - Production applications with distributed architecture
|
|
57
|
-
*
|
|
58
|
-
* For production multi-server deployments, implement WorkloadTokenStore with Redis.
|
|
59
|
-
*
|
|
60
|
-
* @template TExtended - Type-safe custom data that consumers can add to cached tokens
|
|
61
|
-
*/
|
|
62
|
-
export class InMemoryWorkloadTokenStore {
|
|
63
|
-
constructor() {
|
|
64
|
-
this.tokens = new Map();
|
|
65
|
-
}
|
|
66
|
-
async set(token) {
|
|
67
|
-
this.tokens.set(token.workload_id, token);
|
|
68
|
-
}
|
|
69
|
-
async get(workload_id) {
|
|
70
|
-
const token = this.tokens.get(workload_id);
|
|
71
|
-
if (!token)
|
|
72
|
-
return null;
|
|
73
|
-
// Check if token is expired
|
|
74
|
-
if (Date.now() > token.expires_at.getTime()) {
|
|
75
|
-
this.tokens.delete(workload_id);
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
return token;
|
|
79
|
-
}
|
|
80
|
-
async delete(workload_id) {
|
|
81
|
-
this.tokens.delete(workload_id);
|
|
82
|
-
}
|
|
83
|
-
async isValid(workload_id) {
|
|
84
|
-
const token = await this.get(workload_id);
|
|
85
|
-
return token !== null;
|
|
86
|
-
}
|
|
87
|
-
async cleanup() {
|
|
88
|
-
const now = Date.now();
|
|
89
|
-
for (const [workload_id, token] of this.tokens.entries()) {
|
|
90
|
-
if (now > token.expires_at.getTime()) {
|
|
91
|
-
this.tokens.delete(workload_id);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|