@datacules/agent-identity-store-spiffe 0.2.1

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.
Files changed (2) hide show
  1. package/README.md +106 -0
  2. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # `@datacules/agent-identity-store-spiffe`
2
+
3
+ SPIFFE/SPIRE workload identity credential store for [`@datacules/agent-identity`](https://github.com/hvrcharon1/agent-identity).
4
+
5
+ Instead of static long-lived API keys stored in a vault, this store uses the **SPIFFE Workload API** to fetch short-lived **X.509 SVIDs** (SPIFFE Verifiable Identity Documents) on demand. A full store compromise yields only workload metadata — no usable credential material.
6
+
7
+ ---
8
+
9
+ ## How it works
10
+
11
+ 1. On `resolve()`, the store looks up credential metadata by `ref`.
12
+ 2. It calls the SPIRE Workload API socket to fetch the current X.509 SVID bundle for that workload.
13
+ 3. The SVID's PEM certificate chain is returned as the live credential value.
14
+ 4. Downstream services verify the chain against the trust bundle — no static API key ever travels over the wire.
15
+ 5. SVIDs are cached in memory until 5 minutes before expiry (configurable), then re-fetched transparently.
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @datacules/agent-identity-store-spiffe @spiffe/spiffe-workload-api
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Usage
28
+
29
+ ```typescript
30
+ import { SpiffeCredentialStore } from '@datacules/agent-identity-store-spiffe';
31
+ import { createRouterFromStore } from '@datacules/agent-identity';
32
+
33
+ const store = new SpiffeCredentialStore({
34
+ trustDomain: 'acme.org',
35
+ endpointSocket: 'unix:///run/spire/sockets/agent.sock', // or SPIFFE_ENDPOINT_SOCKET env
36
+ credentials: [
37
+ {
38
+ id: 'cred-orders-service',
39
+ ref: 'orders-service', // matched against SVID hint or path segment
40
+ kind: 'fixed',
41
+ name: 'Orders service workload identity',
42
+ scope: 'all',
43
+ status: 'active',
44
+ provider: 'local',
45
+ },
46
+ ],
47
+ });
48
+
49
+ const router = createRouterFromStore(store, rules, logger);
50
+ const resolved = await router.resolveAsync(ctx);
51
+ // resolved.ref contains the PEM X.509 SVID — pass it to mTLS or a
52
+ // downstream service that verifies SPIFFE SVIDs
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Configuration
58
+
59
+ | Option | Type | Default | Description |
60
+ |--------|------|---------|-------------|
61
+ | `credentials` | `Credential[]` | required | Static metadata for each workload |
62
+ | `endpointSocket` | `string` | `SPIFFE_ENDPOINT_SOCKET` env or `/tmp/spire-agent/public/api.sock` | SPIFFE Workload API socket path |
63
+ | `trustDomain` | `string` | `example.org` | SPIFFE trust domain (e.g. `acme.org`) |
64
+ | `cacheTtlSeconds` | `number` | `3300` (55 min) | How long to cache SVIDs before re-fetching |
65
+
66
+ ---
67
+
68
+ ## SVID matching
69
+
70
+ The store matches a credential `ref` to an SVID using three strategies (first match wins):
71
+
72
+ 1. **Hint match** — SVID `hint` field equals the credential `ref`
73
+ 2. **Path suffix** — SPIFFE ID ends with `/<ref>` (e.g. `spiffe://acme.org/orders-service`)
74
+ 3. **Exact SPIFFE ID** — SPIFFE ID equals `spiffe://<trustDomain>/<ref>`
75
+
76
+ ---
77
+
78
+ ## SPIRE server setup
79
+
80
+ ```bash
81
+ # Register a workload entry for your service
82
+ spire-server entry create \
83
+ -spiffeID spiffe://acme.org/orders-service \
84
+ -parentID spiffe://acme.org/agent/prod \
85
+ -selector k8s:pod-label:app:orders-service
86
+
87
+ # The SPIRE agent on the node will attest the workload and issue SVIDs
88
+ # automatically. No API key management required.
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Zero-trust architecture
94
+
95
+ Combine with `@datacules/agent-identity-otel` for full observability:
96
+
97
+ ```typescript
98
+ import { withOtel } from '@datacules/agent-identity-otel';
99
+
100
+ const router = withOtel(
101
+ createRouterFromStore(spiffeStore, rules, logger),
102
+ { tracer: trace.getTracer('agent-identity') }
103
+ );
104
+ ```
105
+
106
+ Every SVID fetch, cache hit/miss, and credential resolution is traced.
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@datacules/agent-identity-store-spiffe",
3
+ "version": "0.2.1",
4
+ "description": "SPIFFE/SPIRE workload identity credential store for @datacules/agent-identity",
5
+ "private": false,
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/esm/index.js",
10
+ "require": "./dist/cjs/index.js",
11
+ "types": "./dist/types/index.d.ts"
12
+ }
13
+ },
14
+ "main": "./dist/cjs/index.js",
15
+ "module": "./dist/esm/index.js",
16
+ "types": "./dist/types/index.d.ts",
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.build.json && tsc -p tsconfig.cjs.json",
23
+ "type-check": "tsc --noEmit"
24
+ },
25
+ "dependencies": {
26
+ "@datacules/agent-identity": "*"
27
+ },
28
+ "peerDependencies": {
29
+ "@spiffe/spiffe-workload-api": "^1.0.0"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "@spiffe/spiffe-workload-api": {
33
+ "optional": true
34
+ }
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5"
38
+ },
39
+ "license": "MIT",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/hvrcharon1/agent-identity"
43
+ }
44
+ }