@zauso-ai/capstan-auth 0.2.0 → 0.3.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/dist/dpop.d.ts +46 -0
- package/dist/dpop.d.ts.map +1 -0
- package/dist/dpop.js +259 -0
- package/dist/dpop.js.map +1 -0
- package/dist/execution.d.ts +10 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +50 -0
- package/dist/execution.js.map +1 -0
- package/dist/harness-authorizer.d.ts +10 -0
- package/dist/harness-authorizer.d.ts.map +1 -0
- package/dist/harness-authorizer.js +90 -0
- package/dist/harness-authorizer.js.map +1 -0
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +6 -3
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +209 -30
- package/dist/middleware.js.map +1 -1
- package/dist/oauth.d.ts +47 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +199 -0
- package/dist/oauth.js.map +1 -0
- package/dist/permissions.d.ts +12 -22
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +91 -33
- package/dist/permissions.js.map +1 -1
- package/dist/runtime-authorizer.d.ts +28 -0
- package/dist/runtime-authorizer.d.ts.map +1 -0
- package/dist/runtime-authorizer.js +136 -0
- package/dist/runtime-authorizer.js.map +1 -0
- package/dist/runtime-grants.d.ts +31 -0
- package/dist/runtime-grants.d.ts.map +1 -0
- package/dist/runtime-grants.js +96 -0
- package/dist/runtime-grants.js.map +1 -0
- package/dist/session.d.ts +3 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +21 -3
- package/dist/session.js.map +1 -1
- package/dist/store.d.ts +27 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +46 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +109 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/workload.d.ts +46 -0
- package/dist/workload.d.ts.map +1 -0
- package/dist/workload.js +227 -0
- package/dist/workload.js.map +1 -0
- package/package.json +3 -2
package/dist/types.d.ts
CHANGED
|
@@ -1,40 +1,148 @@
|
|
|
1
|
+
export type AuthContextType = "human" | "agent" | "anonymous" | "workload";
|
|
2
|
+
export type ActorKind = "user" | "agent" | "workload" | "system" | "anonymous";
|
|
3
|
+
export type CredentialKind = "session" | "oauth" | "api_key" | "mtls" | "dpop" | "run_token" | "approval_token" | "anonymous";
|
|
4
|
+
export type ExecutionKind = "request" | "run" | "tool_call" | "approval" | "schedule" | "release" | "mcp_invocation";
|
|
5
|
+
export interface AuthCookieConfig {
|
|
6
|
+
path?: string;
|
|
7
|
+
domain?: string;
|
|
8
|
+
secure?: boolean;
|
|
9
|
+
httpOnly?: boolean;
|
|
10
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
11
|
+
}
|
|
12
|
+
export interface AuthGrant {
|
|
13
|
+
resource: string;
|
|
14
|
+
action: string;
|
|
15
|
+
scope?: Record<string, string>;
|
|
16
|
+
effect?: "allow" | "deny";
|
|
17
|
+
expiresAt?: string;
|
|
18
|
+
constraints?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface AuthGrantRequirement {
|
|
21
|
+
resource: string;
|
|
22
|
+
action: string;
|
|
23
|
+
scope?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
export interface ActorIdentity {
|
|
26
|
+
kind: ActorKind;
|
|
27
|
+
id: string;
|
|
28
|
+
displayName?: string;
|
|
29
|
+
role?: string;
|
|
30
|
+
email?: string;
|
|
31
|
+
claims?: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
export interface CredentialProof {
|
|
34
|
+
kind: CredentialKind;
|
|
35
|
+
subjectId: string;
|
|
36
|
+
presentedAt: string;
|
|
37
|
+
expiresAt?: string;
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
export interface ExecutionIdentity {
|
|
41
|
+
kind: ExecutionKind;
|
|
42
|
+
id: string;
|
|
43
|
+
parentId?: string;
|
|
44
|
+
metadata?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
export interface DelegationTargetRef {
|
|
47
|
+
kind: ActorKind | ExecutionKind;
|
|
48
|
+
id: string;
|
|
49
|
+
}
|
|
50
|
+
export interface DelegationLink {
|
|
51
|
+
from: DelegationTargetRef;
|
|
52
|
+
to: DelegationTargetRef;
|
|
53
|
+
reason: string;
|
|
54
|
+
issuedAt: string;
|
|
55
|
+
metadata?: Record<string, unknown>;
|
|
56
|
+
}
|
|
57
|
+
export interface AuthEnvelope {
|
|
58
|
+
actor: ActorIdentity;
|
|
59
|
+
credential: CredentialProof;
|
|
60
|
+
execution?: ExecutionIdentity;
|
|
61
|
+
delegation: DelegationLink[];
|
|
62
|
+
grants: AuthGrant[];
|
|
63
|
+
}
|
|
1
64
|
export interface AuthConfig {
|
|
2
65
|
session: {
|
|
3
66
|
secret: string;
|
|
4
67
|
maxAge?: string;
|
|
68
|
+
issuer?: string;
|
|
69
|
+
audience?: string;
|
|
70
|
+
cookieName?: string;
|
|
71
|
+
cookie?: AuthCookieConfig;
|
|
5
72
|
};
|
|
6
73
|
apiKeys?: {
|
|
7
74
|
prefix?: string;
|
|
8
75
|
headerName?: string;
|
|
9
76
|
};
|
|
77
|
+
/** Trusted SPIFFE trust domains for mTLS workload authentication. */
|
|
78
|
+
trustedDomains?: string[];
|
|
79
|
+
/** Whether to require client certificates (mTLS). */
|
|
80
|
+
mtls?: boolean;
|
|
81
|
+
/** OAuth 2.0 provider configuration for Google, GitHub, etc. */
|
|
82
|
+
oauth?: import("./oauth.js").OAuthConfig;
|
|
10
83
|
}
|
|
11
84
|
export interface SessionPayload {
|
|
12
85
|
userId: string;
|
|
13
86
|
email?: string;
|
|
14
87
|
role?: string;
|
|
88
|
+
displayName?: string;
|
|
89
|
+
permissions?: string[];
|
|
90
|
+
claims?: Record<string, unknown>;
|
|
91
|
+
sessionId?: string;
|
|
92
|
+
iss?: string;
|
|
93
|
+
aud?: string | string[];
|
|
15
94
|
iat: number;
|
|
16
95
|
exp: number;
|
|
17
96
|
}
|
|
97
|
+
export interface SessionSigningOptions {
|
|
98
|
+
maxAge?: string;
|
|
99
|
+
issuer?: string;
|
|
100
|
+
audience?: string | string[];
|
|
101
|
+
}
|
|
102
|
+
export interface SessionVerificationOptions {
|
|
103
|
+
issuer?: string;
|
|
104
|
+
audience?: string;
|
|
105
|
+
}
|
|
18
106
|
export interface AgentCredential {
|
|
19
107
|
id: string;
|
|
20
108
|
name: string;
|
|
21
109
|
apiKeyHash: string;
|
|
22
110
|
apiKeyPrefix: string;
|
|
23
111
|
permissions: string[];
|
|
112
|
+
grants?: AuthGrant[];
|
|
113
|
+
claims?: Record<string, unknown>;
|
|
24
114
|
revokedAt?: string;
|
|
25
115
|
}
|
|
26
116
|
export interface AuthContext {
|
|
27
117
|
isAuthenticated: boolean;
|
|
28
|
-
type:
|
|
118
|
+
type: AuthContextType;
|
|
119
|
+
actor: ActorIdentity;
|
|
120
|
+
credential: CredentialProof;
|
|
121
|
+
execution?: ExecutionIdentity;
|
|
122
|
+
delegation: DelegationLink[];
|
|
123
|
+
grants: AuthGrant[];
|
|
124
|
+
envelope?: AuthEnvelope;
|
|
29
125
|
userId?: string;
|
|
30
126
|
role?: string;
|
|
31
127
|
email?: string;
|
|
32
128
|
agentId?: string;
|
|
33
129
|
agentName?: string;
|
|
34
130
|
permissions?: string[];
|
|
131
|
+
/** DPoP key thumbprint — present when the request included a valid DPoP proof. */
|
|
132
|
+
dpopThumbprint?: string;
|
|
133
|
+
/** SPIFFE ID from client certificate (e.g. "spiffe://example.org/agent/crawler"). */
|
|
134
|
+
spiffeId?: string;
|
|
135
|
+
/** Client certificate fingerprint (SHA-256 hex digest). */
|
|
136
|
+
certFingerprint?: string;
|
|
35
137
|
}
|
|
36
138
|
export interface AuthResolverDeps {
|
|
37
139
|
/** Look up an agent credential by API key prefix */
|
|
38
140
|
findAgentByKeyPrefix?: (prefix: string) => Promise<AgentCredential | null>;
|
|
141
|
+
/** Resolve extra grants after credential verification. */
|
|
142
|
+
resolveAdditionalGrants?: (auth: AuthContext, request: Request) => Promise<AuthGrant[] | string[] | undefined>;
|
|
143
|
+
/** Attach richer execution identity to the resolved auth envelope. */
|
|
144
|
+
resolveExecution?: (auth: AuthContext, request: Request) => Promise<ExecutionIdentity | undefined>;
|
|
145
|
+
/** Attach delegation provenance for runtime / harness flows. */
|
|
146
|
+
resolveDelegation?: (auth: AuthContext, request: Request) => Promise<DelegationLink[] | undefined>;
|
|
39
147
|
}
|
|
40
148
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/E,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,MAAM,GACN,WAAW,GACX,gBAAgB,GAChB,WAAW,CAAC;AAEhB,MAAM,MAAM,aAAa,GACrB,SAAS,GACT,KAAK,GACL,WAAW,GACX,UAAU,GACV,UAAU,GACV,SAAS,GACT,gBAAgB,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,aAAa,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,mBAAmB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,gBAAgB,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,YAAY,EAAE,WAAW,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACrC,0DAA0D;IAC1D,uBAAuB,CAAC,EAAE,CACxB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,SAAS,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACjD,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CACjB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC5C,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,CAClB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,cAAc,EAAE,GAAG,SAAS,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed workload identity extracted from a client certificate.
|
|
3
|
+
*/
|
|
4
|
+
export interface WorkloadIdentity {
|
|
5
|
+
/** Full SPIFFE ID URI (e.g. "spiffe://example.org/agent/crawler"). */
|
|
6
|
+
spiffeId: string;
|
|
7
|
+
/** Trust domain portion of the SPIFFE ID (e.g. "example.org"). */
|
|
8
|
+
trustDomain: string;
|
|
9
|
+
/** Workload path portion of the SPIFFE ID (e.g. "/agent/crawler"). */
|
|
10
|
+
workloadPath: string;
|
|
11
|
+
/** SHA-256 hex digest of the PEM-encoded client certificate. */
|
|
12
|
+
certFingerprint: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validate that a string is a well-formed SPIFFE ID per the SPIFFE spec:
|
|
16
|
+
*
|
|
17
|
+
* - Scheme must be `spiffe`
|
|
18
|
+
* - Trust domain must be a non-empty hostname-like string (lower-case
|
|
19
|
+
* alphanumerics, hyphens, dots; no leading/trailing hyphens or dots).
|
|
20
|
+
* - Workload path must be non-empty and start with `/`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isValidSpiffeId(id: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Extract a workload identity from client certificate information provided
|
|
25
|
+
* via request headers.
|
|
26
|
+
*
|
|
27
|
+
* In a typical deployment the mTLS termination happens at a reverse proxy
|
|
28
|
+
* (Envoy, Nginx, Istio ingress, etc.) which forwards the client certificate
|
|
29
|
+
* and its SPIFFE ID through HTTP headers.
|
|
30
|
+
*
|
|
31
|
+
* Supported header combinations:
|
|
32
|
+
*
|
|
33
|
+
* | SPIFFE ID source | Cert source |
|
|
34
|
+
* |---------------------------------------|--------------------------|
|
|
35
|
+
* | `X-Client-Cert-Spiffe-Id` header | `X-Client-Cert` |
|
|
36
|
+
* | `URI=` in `X-Forwarded-Client-Cert` | `X-Forwarded-Client-Cert`|
|
|
37
|
+
*
|
|
38
|
+
* @param certOrHeaders PEM-encoded client certificate string, or a
|
|
39
|
+
* header map (e.g. from `Object.fromEntries(request.headers)`).
|
|
40
|
+
* @param trustedDomains Whitelist of SPIFFE trust domains to accept.
|
|
41
|
+
* @returns The parsed `WorkloadIdentity` if the certificate is present, the
|
|
42
|
+
* SPIFFE ID is valid, and the trust domain is in the whitelist.
|
|
43
|
+
* Returns `null` otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractWorkloadIdentity(certOrHeaders: string | Record<string, string | undefined>, trustedDomains: string[]): WorkloadIdentity | null;
|
|
46
|
+
//# sourceMappingURL=workload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload.d.ts","sourceRoot":"","sources":["../src/workload.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,eAAe,EAAE,MAAM,CAAC;CACzB;AAiBD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CA6BnD;AAkID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC1D,cAAc,EAAE,MAAM,EAAE,GACvB,gBAAgB,GAAG,IAAI,CAyCzB"}
|
package/dist/workload.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Headers that reverse proxies commonly use to forward client certificates.
|
|
4
|
+
*
|
|
5
|
+
* - `x-client-cert` — raw PEM or URL-encoded PEM (Envoy, Nginx, etc.)
|
|
6
|
+
* - `x-forwarded-client-cert` — Envoy XFCC header (may contain key=value pairs)
|
|
7
|
+
*/
|
|
8
|
+
const CLIENT_CERT_HEADERS = [
|
|
9
|
+
"x-client-cert",
|
|
10
|
+
"x-forwarded-client-cert",
|
|
11
|
+
];
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// SPIFFE ID validation
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Validate that a string is a well-formed SPIFFE ID per the SPIFFE spec:
|
|
17
|
+
*
|
|
18
|
+
* - Scheme must be `spiffe`
|
|
19
|
+
* - Trust domain must be a non-empty hostname-like string (lower-case
|
|
20
|
+
* alphanumerics, hyphens, dots; no leading/trailing hyphens or dots).
|
|
21
|
+
* - Workload path must be non-empty and start with `/`.
|
|
22
|
+
*/
|
|
23
|
+
export function isValidSpiffeId(id) {
|
|
24
|
+
if (typeof id !== "string" || id.length === 0)
|
|
25
|
+
return false;
|
|
26
|
+
// Must start with the spiffe scheme.
|
|
27
|
+
if (!id.startsWith("spiffe://"))
|
|
28
|
+
return false;
|
|
29
|
+
const rest = id.slice("spiffe://".length);
|
|
30
|
+
// Find the first "/" after the trust domain.
|
|
31
|
+
const slashIndex = rest.indexOf("/");
|
|
32
|
+
if (slashIndex <= 0)
|
|
33
|
+
return false; // no trust domain or no path
|
|
34
|
+
const trustDomain = rest.slice(0, slashIndex);
|
|
35
|
+
const workloadPath = rest.slice(slashIndex);
|
|
36
|
+
// Trust domain: valid DNS-like label(s), no leading/trailing dot or hyphen.
|
|
37
|
+
if (!isValidTrustDomain(trustDomain))
|
|
38
|
+
return false;
|
|
39
|
+
// Workload path must be non-empty (beyond the leading slash).
|
|
40
|
+
if (workloadPath.length < 2)
|
|
41
|
+
return false;
|
|
42
|
+
// Path segments must not be empty (no double slashes) and must not
|
|
43
|
+
// contain `.` or `..` traversals.
|
|
44
|
+
const segments = workloadPath.slice(1).split("/");
|
|
45
|
+
for (const seg of segments) {
|
|
46
|
+
if (seg.length === 0 || seg === "." || seg === "..")
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A trust domain is a valid lower-case DNS name: labels separated by dots,
|
|
53
|
+
* each label consisting of alphanumerics and hyphens, not starting/ending
|
|
54
|
+
* with a hyphen.
|
|
55
|
+
*/
|
|
56
|
+
function isValidTrustDomain(domain) {
|
|
57
|
+
if (domain.length === 0 || domain.length > 255)
|
|
58
|
+
return false;
|
|
59
|
+
const labels = domain.split(".");
|
|
60
|
+
for (const label of labels) {
|
|
61
|
+
if (label.length === 0 || label.length > 63)
|
|
62
|
+
return false;
|
|
63
|
+
if (/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(label) === false)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Certificate parsing helpers
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
/**
|
|
72
|
+
* Extract the PEM-encoded client certificate from request headers.
|
|
73
|
+
*
|
|
74
|
+
* Supports:
|
|
75
|
+
* - `X-Client-Cert: <PEM or URL-encoded PEM>`
|
|
76
|
+
* - `X-Forwarded-Client-Cert: Cert="<URL-encoded PEM>"` (Envoy XFCC format)
|
|
77
|
+
*/
|
|
78
|
+
function extractPemFromHeaders(headers) {
|
|
79
|
+
// Normalise header names to lower case for case-insensitive lookup.
|
|
80
|
+
const normalised = {};
|
|
81
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
82
|
+
if (v !== undefined) {
|
|
83
|
+
normalised[k.toLowerCase()] = v;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const headerName of CLIENT_CERT_HEADERS) {
|
|
87
|
+
const raw = normalised[headerName];
|
|
88
|
+
if (!raw || raw.length === 0)
|
|
89
|
+
continue;
|
|
90
|
+
// XFCC header from Envoy may look like:
|
|
91
|
+
// By=...;Cert="<url-encoded PEM>";Hash=...
|
|
92
|
+
// Extract the Cert value if present.
|
|
93
|
+
const certMatch = raw.match(/Cert="([^"]+)"/i);
|
|
94
|
+
if (certMatch?.[1]) {
|
|
95
|
+
return decodePem(certMatch[1]);
|
|
96
|
+
}
|
|
97
|
+
// Otherwise treat the entire header value as PEM (possibly URL-encoded).
|
|
98
|
+
return decodePem(raw);
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Decode a PEM string that may be URL-encoded (common in proxy headers).
|
|
104
|
+
*/
|
|
105
|
+
function decodePem(value) {
|
|
106
|
+
// If the value contains %2F or %2B it was URL-encoded.
|
|
107
|
+
if (value.includes("%")) {
|
|
108
|
+
try {
|
|
109
|
+
return decodeURIComponent(value);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Not valid URL encoding — use as-is.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Compute the SHA-256 hex fingerprint of a PEM-encoded certificate.
|
|
119
|
+
*
|
|
120
|
+
* The fingerprint is computed over the raw PEM text (including header/footer
|
|
121
|
+
* lines) to keep the implementation dependency-free. This is sufficient for
|
|
122
|
+
* identity-binding purposes as each unique cert will produce a unique hash.
|
|
123
|
+
*/
|
|
124
|
+
function computeCertFingerprint(pem) {
|
|
125
|
+
return createHash("sha256").update(pem).digest("hex");
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Extract the SPIFFE URI SAN from a PEM-encoded certificate.
|
|
129
|
+
*
|
|
130
|
+
* Real X.509 parsing requires ASN.1 decoding which would need a dependency.
|
|
131
|
+
* Instead we use a pragmatic approach: the SPIFFE ID is looked up from a
|
|
132
|
+
* companion header (`X-Client-Cert-Spiffe-Id`) that mTLS-terminating proxies
|
|
133
|
+
* (Envoy, Istio, Linkerd) can be configured to set, or it can be embedded
|
|
134
|
+
* in the XFCC header as `URI=spiffe://...`.
|
|
135
|
+
*
|
|
136
|
+
* If neither is available we fall back to scanning the PEM base64 payload
|
|
137
|
+
* for the `spiffe://` URI (works for unencrypted certs where the SAN is
|
|
138
|
+
* visible in the base64 text — a useful heuristic but not a substitute for
|
|
139
|
+
* real ASN.1 parsing).
|
|
140
|
+
*/
|
|
141
|
+
function extractSpiffeIdFromHeaders(headers) {
|
|
142
|
+
const normalised = {};
|
|
143
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
144
|
+
if (v !== undefined) {
|
|
145
|
+
normalised[k.toLowerCase()] = v;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 1. Explicit header set by the proxy.
|
|
149
|
+
const explicit = normalised["x-client-cert-spiffe-id"];
|
|
150
|
+
if (explicit && isValidSpiffeId(explicit)) {
|
|
151
|
+
return explicit;
|
|
152
|
+
}
|
|
153
|
+
// 2. XFCC URI field (Envoy sets `URI=spiffe://...`).
|
|
154
|
+
const xfcc = normalised["x-forwarded-client-cert"];
|
|
155
|
+
if (xfcc) {
|
|
156
|
+
const uriMatch = xfcc.match(/URI=(spiffe:\/\/[^;,"]+)/i);
|
|
157
|
+
if (uriMatch?.[1] && isValidSpiffeId(uriMatch[1])) {
|
|
158
|
+
return uriMatch[1];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
// Public API
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
/**
|
|
167
|
+
* Extract a workload identity from client certificate information provided
|
|
168
|
+
* via request headers.
|
|
169
|
+
*
|
|
170
|
+
* In a typical deployment the mTLS termination happens at a reverse proxy
|
|
171
|
+
* (Envoy, Nginx, Istio ingress, etc.) which forwards the client certificate
|
|
172
|
+
* and its SPIFFE ID through HTTP headers.
|
|
173
|
+
*
|
|
174
|
+
* Supported header combinations:
|
|
175
|
+
*
|
|
176
|
+
* | SPIFFE ID source | Cert source |
|
|
177
|
+
* |---------------------------------------|--------------------------|
|
|
178
|
+
* | `X-Client-Cert-Spiffe-Id` header | `X-Client-Cert` |
|
|
179
|
+
* | `URI=` in `X-Forwarded-Client-Cert` | `X-Forwarded-Client-Cert`|
|
|
180
|
+
*
|
|
181
|
+
* @param certOrHeaders PEM-encoded client certificate string, or a
|
|
182
|
+
* header map (e.g. from `Object.fromEntries(request.headers)`).
|
|
183
|
+
* @param trustedDomains Whitelist of SPIFFE trust domains to accept.
|
|
184
|
+
* @returns The parsed `WorkloadIdentity` if the certificate is present, the
|
|
185
|
+
* SPIFFE ID is valid, and the trust domain is in the whitelist.
|
|
186
|
+
* Returns `null` otherwise.
|
|
187
|
+
*/
|
|
188
|
+
export function extractWorkloadIdentity(certOrHeaders, trustedDomains) {
|
|
189
|
+
if (trustedDomains.length === 0)
|
|
190
|
+
return null;
|
|
191
|
+
let pem;
|
|
192
|
+
let spiffeId;
|
|
193
|
+
if (typeof certOrHeaders === "string") {
|
|
194
|
+
// Raw PEM string provided directly — cannot extract SPIFFE ID from
|
|
195
|
+
// headers, so this path is only useful if the caller also provides
|
|
196
|
+
// the SPIFFE ID separately. For header-based flows use the object form.
|
|
197
|
+
pem = certOrHeaders.length > 0 ? certOrHeaders : null;
|
|
198
|
+
spiffeId = null;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
pem = extractPemFromHeaders(certOrHeaders);
|
|
202
|
+
spiffeId = extractSpiffeIdFromHeaders(certOrHeaders);
|
|
203
|
+
}
|
|
204
|
+
// We need both a certificate (for fingerprinting) and a SPIFFE ID.
|
|
205
|
+
if (!pem || !spiffeId)
|
|
206
|
+
return null;
|
|
207
|
+
if (!isValidSpiffeId(spiffeId))
|
|
208
|
+
return null;
|
|
209
|
+
// Parse the trust domain from the SPIFFE ID.
|
|
210
|
+
const rest = spiffeId.slice("spiffe://".length);
|
|
211
|
+
const slashIndex = rest.indexOf("/");
|
|
212
|
+
if (slashIndex <= 0)
|
|
213
|
+
return null;
|
|
214
|
+
const trustDomain = rest.slice(0, slashIndex);
|
|
215
|
+
const workloadPath = rest.slice(slashIndex);
|
|
216
|
+
// Verify the trust domain is in the whitelist.
|
|
217
|
+
if (!trustedDomains.includes(trustDomain))
|
|
218
|
+
return null;
|
|
219
|
+
const certFingerprint = computeCertFingerprint(pem);
|
|
220
|
+
return {
|
|
221
|
+
spiffeId,
|
|
222
|
+
trustDomain,
|
|
223
|
+
workloadPath,
|
|
224
|
+
certFingerprint,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=workload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload.js","sourceRoot":"","sources":["../src/workload.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauso-ai/capstan-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc -p tsconfig.json",
|
|
15
|
-
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
15
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
16
|
+
"clean": "rm -rf dist"
|
|
16
17
|
},
|
|
17
18
|
"description": "Authentication for Capstan — JWT sessions, API key auth for AI agents, permissions",
|
|
18
19
|
"files": [
|