@predicatesystems/temporal 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Predicate Systems
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # @predicatesystems/temporal
2
+
3
+ Temporal.io Worker Interceptor for Predicate Authority Zero-Trust authorization.
4
+
5
+ This package provides a pre-execution security gate for all Temporal Activities, enforcing cryptographic authorization mandates before any activity code runs.
6
+
7
+ ## Prerequisites
8
+
9
+ This package requires the **Predicate Authority Sidecar** daemon to be running. The sidecar is a lightweight Rust binary that handles policy evaluation and mandate signing.
10
+
11
+ | Resource | Link |
12
+ |----------|------|
13
+ | Sidecar Repository | [github.com/PredicateSystems/predicate-authority-sidecar](https://github.com/PredicateSystems/predicate-authority-sidecar) |
14
+ | Download Binaries | [Latest Releases](https://github.com/PredicateSystems/predicate-authority-sidecar/releases) |
15
+ | License | MIT / Apache 2.0 |
16
+
17
+ ### Quick Sidecar Setup
18
+
19
+ ```bash
20
+ # Download the latest release for your platform
21
+ # Linux x64, macOS x64/ARM64, Windows x64 available
22
+
23
+ # Extract and run
24
+ tar -xzf predicate-authorityd-*.tar.gz
25
+ chmod +x predicate-authorityd
26
+
27
+ # Start with a policy file
28
+ ./predicate-authorityd --port 8787 --policy-file policy.json
29
+ ```
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install @predicatesystems/temporal
35
+ # or
36
+ yarn add @predicatesystems/temporal
37
+ # or
38
+ pnpm add @predicatesystems/temporal
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```typescript
44
+ import { Worker } from "@temporalio/worker";
45
+ import { AuthorityClient } from "@predicatesystems/authority";
46
+ import { createPredicateInterceptors } from "@predicatesystems/temporal";
47
+
48
+ // Initialize the Predicate Authority client
49
+ const authorityClient = new AuthorityClient({
50
+ baseUrl: "http://127.0.0.1:8787",
51
+ });
52
+
53
+ // Create interceptors
54
+ const interceptors = createPredicateInterceptors({
55
+ authorityClient,
56
+ principal: "temporal-worker",
57
+ });
58
+
59
+ // Create worker with the interceptors
60
+ const worker = await Worker.create({
61
+ connection,
62
+ namespace: "default",
63
+ taskQueue: "my-task-queue",
64
+ workflowsPath: require.resolve("./workflows"),
65
+ activities,
66
+ interceptors,
67
+ });
68
+ ```
69
+
70
+ ## How It Works
71
+
72
+ The interceptor sits in the Temporal activity execution pipeline:
73
+
74
+ 1. Temporal dispatches an activity to your worker
75
+ 2. **Before** the activity code runs, the interceptor extracts:
76
+ - Activity type (action)
77
+ - Activity arguments (context)
78
+ 3. The interceptor calls `AuthorityClient.authorize()` to request a mandate
79
+ 4. If **denied**: throws `PredicateAuthorizationError` - activity never executes
80
+ 5. If **approved**: activity proceeds normally
81
+
82
+ This ensures that no untrusted code or payload reaches your OS until it has been cryptographically authorized.
83
+
84
+ ## Configuration
85
+
86
+ ### Interceptor Options
87
+
88
+ ```typescript
89
+ import { createPredicateInterceptors } from "@predicatesystems/temporal";
90
+
91
+ const interceptors = createPredicateInterceptors({
92
+ // Required: The Predicate Authority client
93
+ authorityClient: new AuthorityClient({ baseUrl: "http://127.0.0.1:8787" }),
94
+
95
+ // Optional: Principal ID (default: "temporal-worker")
96
+ principal: "my-worker",
97
+
98
+ // Optional: Tenant ID for multi-tenant setups
99
+ tenantId: "tenant-123",
100
+
101
+ // Optional: Session ID for request correlation
102
+ sessionId: "session-456",
103
+
104
+ // Optional: Custom resource identifier (default: "temporal:activity")
105
+ resource: "temporal:my-queue",
106
+ });
107
+ ```
108
+
109
+ ### Policy File
110
+
111
+ Create a policy file for the Predicate Authority daemon:
112
+
113
+ ```json
114
+ {
115
+ "rules": [
116
+ {
117
+ "name": "allow-safe-activities",
118
+ "effect": "allow",
119
+ "principals": ["temporal-worker"],
120
+ "actions": ["processOrder", "sendNotification"],
121
+ "resources": ["*"]
122
+ },
123
+ {
124
+ "name": "deny-dangerous-activities",
125
+ "effect": "deny",
126
+ "principals": ["*"],
127
+ "actions": ["delete*", "admin*"],
128
+ "resources": ["*"]
129
+ }
130
+ ]
131
+ }
132
+ ```
133
+
134
+ ## API Reference
135
+
136
+ ### `createPredicateInterceptors(options)`
137
+
138
+ Creates the interceptor configuration object for `Worker.create()`.
139
+
140
+ **Parameters:**
141
+
142
+ - `options.authorityClient` (required): `AuthorityClient` - The Predicate Authority client instance
143
+ - `options.principal` (optional): `string` - Principal ID (default: `"temporal-worker"`)
144
+ - `options.tenantId` (optional): `string` - Tenant ID for multi-tenant setups
145
+ - `options.sessionId` (optional): `string` - Session ID for request correlation
146
+ - `options.resource` (optional): `string` - Resource identifier (default: `"temporal:activity"`)
147
+
148
+ **Returns:** `WorkerInterceptors` - The interceptor configuration for Temporal Worker
149
+
150
+ ### `PredicateActivityInterceptor`
151
+
152
+ The activity interceptor class. Usually you don't need to instantiate this directly - use `createPredicateInterceptors()` instead.
153
+
154
+ ### `PredicateAuthorizationError`
155
+
156
+ Custom error thrown when authorization is denied.
157
+
158
+ ```typescript
159
+ import { PredicateAuthorizationError } from "@predicatesystems/temporal";
160
+
161
+ try {
162
+ await workflow.executeActivity("dangerousActivity", args);
163
+ } catch (error) {
164
+ if (error instanceof PredicateAuthorizationError) {
165
+ console.log(`Denied: ${error.reason}`);
166
+ console.log(`Violated rule: ${error.violatedRule}`);
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Error Handling
172
+
173
+ When authorization is denied, the interceptor throws a `PredicateAuthorizationError`:
174
+
175
+ ```typescript
176
+ import { ApplicationFailure } from "@temporalio/workflow";
177
+
178
+ try {
179
+ await workflow.executeActivity("sensitiveActivity", args, {
180
+ startToCloseTimeout: "30s",
181
+ });
182
+ } catch (error) {
183
+ if (error instanceof ApplicationFailure) {
184
+ // Check if it's a Predicate denial
185
+ if (error.message.includes("Predicate Zero-Trust Denial")) {
186
+ // Handle authorization denial
187
+ console.log("Activity was blocked by security policy");
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ # Install dependencies
197
+ npm install
198
+
199
+ # Build
200
+ npm run build
201
+
202
+ # Run tests
203
+ npm test
204
+
205
+ # Type checking
206
+ npm run typecheck
207
+
208
+ # Linting
209
+ npm run lint
210
+ ```
211
+
212
+ ## License
213
+
214
+ MIT
@@ -0,0 +1,127 @@
1
+ import { Context } from '@temporalio/activity';
2
+ import { ActivityInboundCallsInterceptor, ActivityExecuteInput, Next, WorkerInterceptors } from '@temporalio/worker';
3
+
4
+ /**
5
+ * Predicate Authority interceptor for Temporal.io activities.
6
+ *
7
+ * This module provides a pre-execution security gate for all Temporal Activities,
8
+ * enforcing cryptographic authorization mandates before any activity code runs.
9
+ */
10
+
11
+ /**
12
+ * Interface for the Predicate Authority client.
13
+ * This matches the AuthorityClient from @predicatesystems/authority.
14
+ */
15
+ interface PredicateAuthorityClient {
16
+ authorize(request: PredicateAuthorizeRequest): Promise<PredicateAuthorizationResponse>;
17
+ }
18
+ /**
19
+ * Authorization request sent to the Predicate Authority sidecar.
20
+ */
21
+ interface PredicateAuthorizeRequest {
22
+ principal: string;
23
+ action: string;
24
+ resource: string;
25
+ intent_hash?: string;
26
+ context?: Record<string, unknown>;
27
+ labels?: string[];
28
+ }
29
+ /**
30
+ * Authorization response from the Predicate Authority sidecar.
31
+ */
32
+ interface PredicateAuthorizationResponse {
33
+ allowed: boolean;
34
+ reason: string;
35
+ mandate_id: string | null;
36
+ violated_rule: string | null;
37
+ missing_labels: string[];
38
+ }
39
+ /**
40
+ * Options for creating Predicate interceptors.
41
+ */
42
+ interface PredicateInterceptorOptions {
43
+ /** The Predicate Authority client for authorization */
44
+ authorityClient: PredicateAuthorityClient;
45
+ /** Principal ID used for authorization requests (default: "temporal-worker") */
46
+ principal?: string;
47
+ /** Optional tenant ID for multi-tenant setups */
48
+ tenantId?: string;
49
+ /** Optional session ID for request correlation */
50
+ sessionId?: string;
51
+ /** Optional resource identifier (default: "temporal:activity") */
52
+ resource?: string;
53
+ }
54
+ /**
55
+ * Activity interceptor that enforces Predicate Authority authorization.
56
+ *
57
+ * This interceptor sits in the Temporal activity execution pipeline and ensures
58
+ * that every activity is authorized before execution. If authorization is denied,
59
+ * a PredicateAuthorizationError is thrown and the activity never executes.
60
+ */
61
+ declare class PredicateActivityInterceptor implements ActivityInboundCallsInterceptor {
62
+ private readonly authorityClient;
63
+ private readonly principal;
64
+ private readonly tenantId;
65
+ private readonly sessionId;
66
+ private readonly resource;
67
+ private readonly activityType;
68
+ constructor(ctx: Context, options: PredicateInterceptorOptions);
69
+ /**
70
+ * Execute activity with Predicate Authority authorization check.
71
+ *
72
+ * This method intercepts the activity execution, extracts the activity type
73
+ * and arguments, and requests authorization from Predicate Authority.
74
+ * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.
75
+ */
76
+ execute(input: ActivityExecuteInput, next: Next<ActivityInboundCallsInterceptor, "execute">): Promise<unknown>;
77
+ }
78
+ /**
79
+ * Creates Temporal worker interceptors that enforce Predicate Authority authorization.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * import { Worker } from "@temporalio/worker";
84
+ * import { AuthorityClient } from "@predicatesystems/authority";
85
+ * import { createPredicateInterceptors } from "@predicatesystems/temporal";
86
+ *
87
+ * const authorityClient = new AuthorityClient({
88
+ * baseUrl: "http://127.0.0.1:8787",
89
+ * });
90
+ *
91
+ * const interceptors = createPredicateInterceptors({
92
+ * authorityClient,
93
+ * principal: "temporal-worker",
94
+ * });
95
+ *
96
+ * const worker = await Worker.create({
97
+ * connection,
98
+ * taskQueue: "my-task-queue",
99
+ * workflowsPath: require.resolve("./workflows"),
100
+ * activities,
101
+ * interceptors,
102
+ * });
103
+ * ```
104
+ */
105
+ declare function createPredicateInterceptors(options: PredicateInterceptorOptions): WorkerInterceptors;
106
+
107
+ /**
108
+ * Error thrown when Predicate Authority denies an activity execution.
109
+ */
110
+ declare class PredicateAuthorizationError extends Error {
111
+ /** The authorization reason code */
112
+ readonly reason: string;
113
+ /** The policy rule that caused the denial, if any */
114
+ readonly violatedRule: string | undefined;
115
+ /** Labels that were required but missing */
116
+ readonly missingLabels: readonly string[];
117
+ /** The activity type that was denied */
118
+ readonly activityType: string;
119
+ constructor(options: {
120
+ activityType: string;
121
+ reason: string;
122
+ violatedRule?: string | undefined;
123
+ missingLabels?: readonly string[];
124
+ });
125
+ }
126
+
127
+ export { PredicateActivityInterceptor, PredicateAuthorizationError, type PredicateInterceptorOptions, createPredicateInterceptors };
@@ -0,0 +1,127 @@
1
+ import { Context } from '@temporalio/activity';
2
+ import { ActivityInboundCallsInterceptor, ActivityExecuteInput, Next, WorkerInterceptors } from '@temporalio/worker';
3
+
4
+ /**
5
+ * Predicate Authority interceptor for Temporal.io activities.
6
+ *
7
+ * This module provides a pre-execution security gate for all Temporal Activities,
8
+ * enforcing cryptographic authorization mandates before any activity code runs.
9
+ */
10
+
11
+ /**
12
+ * Interface for the Predicate Authority client.
13
+ * This matches the AuthorityClient from @predicatesystems/authority.
14
+ */
15
+ interface PredicateAuthorityClient {
16
+ authorize(request: PredicateAuthorizeRequest): Promise<PredicateAuthorizationResponse>;
17
+ }
18
+ /**
19
+ * Authorization request sent to the Predicate Authority sidecar.
20
+ */
21
+ interface PredicateAuthorizeRequest {
22
+ principal: string;
23
+ action: string;
24
+ resource: string;
25
+ intent_hash?: string;
26
+ context?: Record<string, unknown>;
27
+ labels?: string[];
28
+ }
29
+ /**
30
+ * Authorization response from the Predicate Authority sidecar.
31
+ */
32
+ interface PredicateAuthorizationResponse {
33
+ allowed: boolean;
34
+ reason: string;
35
+ mandate_id: string | null;
36
+ violated_rule: string | null;
37
+ missing_labels: string[];
38
+ }
39
+ /**
40
+ * Options for creating Predicate interceptors.
41
+ */
42
+ interface PredicateInterceptorOptions {
43
+ /** The Predicate Authority client for authorization */
44
+ authorityClient: PredicateAuthorityClient;
45
+ /** Principal ID used for authorization requests (default: "temporal-worker") */
46
+ principal?: string;
47
+ /** Optional tenant ID for multi-tenant setups */
48
+ tenantId?: string;
49
+ /** Optional session ID for request correlation */
50
+ sessionId?: string;
51
+ /** Optional resource identifier (default: "temporal:activity") */
52
+ resource?: string;
53
+ }
54
+ /**
55
+ * Activity interceptor that enforces Predicate Authority authorization.
56
+ *
57
+ * This interceptor sits in the Temporal activity execution pipeline and ensures
58
+ * that every activity is authorized before execution. If authorization is denied,
59
+ * a PredicateAuthorizationError is thrown and the activity never executes.
60
+ */
61
+ declare class PredicateActivityInterceptor implements ActivityInboundCallsInterceptor {
62
+ private readonly authorityClient;
63
+ private readonly principal;
64
+ private readonly tenantId;
65
+ private readonly sessionId;
66
+ private readonly resource;
67
+ private readonly activityType;
68
+ constructor(ctx: Context, options: PredicateInterceptorOptions);
69
+ /**
70
+ * Execute activity with Predicate Authority authorization check.
71
+ *
72
+ * This method intercepts the activity execution, extracts the activity type
73
+ * and arguments, and requests authorization from Predicate Authority.
74
+ * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.
75
+ */
76
+ execute(input: ActivityExecuteInput, next: Next<ActivityInboundCallsInterceptor, "execute">): Promise<unknown>;
77
+ }
78
+ /**
79
+ * Creates Temporal worker interceptors that enforce Predicate Authority authorization.
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * import { Worker } from "@temporalio/worker";
84
+ * import { AuthorityClient } from "@predicatesystems/authority";
85
+ * import { createPredicateInterceptors } from "@predicatesystems/temporal";
86
+ *
87
+ * const authorityClient = new AuthorityClient({
88
+ * baseUrl: "http://127.0.0.1:8787",
89
+ * });
90
+ *
91
+ * const interceptors = createPredicateInterceptors({
92
+ * authorityClient,
93
+ * principal: "temporal-worker",
94
+ * });
95
+ *
96
+ * const worker = await Worker.create({
97
+ * connection,
98
+ * taskQueue: "my-task-queue",
99
+ * workflowsPath: require.resolve("./workflows"),
100
+ * activities,
101
+ * interceptors,
102
+ * });
103
+ * ```
104
+ */
105
+ declare function createPredicateInterceptors(options: PredicateInterceptorOptions): WorkerInterceptors;
106
+
107
+ /**
108
+ * Error thrown when Predicate Authority denies an activity execution.
109
+ */
110
+ declare class PredicateAuthorizationError extends Error {
111
+ /** The authorization reason code */
112
+ readonly reason: string;
113
+ /** The policy rule that caused the denial, if any */
114
+ readonly violatedRule: string | undefined;
115
+ /** Labels that were required but missing */
116
+ readonly missingLabels: readonly string[];
117
+ /** The activity type that was denied */
118
+ readonly activityType: string;
119
+ constructor(options: {
120
+ activityType: string;
121
+ reason: string;
122
+ violatedRule?: string | undefined;
123
+ missingLabels?: readonly string[];
124
+ });
125
+ }
126
+
127
+ export { PredicateActivityInterceptor, PredicateAuthorizationError, type PredicateInterceptorOptions, createPredicateInterceptors };
package/dist/index.js ADDED
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+
5
+ // src/interceptor.ts
6
+
7
+ // src/errors.ts
8
+ var PredicateAuthorizationError = class extends Error {
9
+ /** The authorization reason code */
10
+ reason;
11
+ /** The policy rule that caused the denial, if any */
12
+ violatedRule;
13
+ /** Labels that were required but missing */
14
+ missingLabels;
15
+ /** The activity type that was denied */
16
+ activityType;
17
+ constructor(options) {
18
+ const message = `Predicate Zero-Trust Denial: Activity '${options.activityType}' not authorized. Reason: ${options.reason}${options.violatedRule ? `, violated rule: ${options.violatedRule}` : ""}`;
19
+ super(message);
20
+ this.name = "PredicateAuthorizationError";
21
+ this.reason = options.reason;
22
+ this.violatedRule = options.violatedRule;
23
+ this.missingLabels = options.missingLabels ?? [];
24
+ this.activityType = options.activityType;
25
+ }
26
+ };
27
+
28
+ // src/interceptor.ts
29
+ var PredicateActivityInterceptor = class {
30
+ authorityClient;
31
+ principal;
32
+ tenantId;
33
+ sessionId;
34
+ resource;
35
+ activityType;
36
+ constructor(ctx, options) {
37
+ this.authorityClient = options.authorityClient;
38
+ this.principal = options.principal ?? "temporal-worker";
39
+ this.tenantId = options.tenantId;
40
+ this.sessionId = options.sessionId;
41
+ this.resource = options.resource ?? "temporal:activity";
42
+ this.activityType = ctx.info.activityType;
43
+ }
44
+ /**
45
+ * Execute activity with Predicate Authority authorization check.
46
+ *
47
+ * This method intercepts the activity execution, extracts the activity type
48
+ * and arguments, and requests authorization from Predicate Authority.
49
+ * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.
50
+ */
51
+ async execute(input, next) {
52
+ const activityArgs = input.args;
53
+ const argsJson = JSON.stringify(activityArgs);
54
+ const argsHash = crypto.createHash("sha256").update(argsJson).digest("hex");
55
+ const request = {
56
+ principal: this.principal,
57
+ action: this.activityType,
58
+ resource: this.resource,
59
+ intent_hash: `ih_execute_${this.activityType.toLowerCase()}`,
60
+ context: {
61
+ state_hash: argsHash,
62
+ tenant_id: this.tenantId,
63
+ session_id: this.sessionId
64
+ }
65
+ };
66
+ const decision = await this.authorityClient.authorize(request);
67
+ if (!decision.allowed) {
68
+ throw new PredicateAuthorizationError({
69
+ activityType: this.activityType,
70
+ reason: decision.reason,
71
+ violatedRule: decision.violated_rule ?? void 0,
72
+ missingLabels: decision.missing_labels ?? []
73
+ });
74
+ }
75
+ return next(input);
76
+ }
77
+ };
78
+ function createPredicateInterceptors(options) {
79
+ const activityInterceptorFactory = (ctx) => ({
80
+ inbound: new PredicateActivityInterceptor(ctx, options)
81
+ });
82
+ return {
83
+ activity: [activityInterceptorFactory]
84
+ };
85
+ }
86
+
87
+ exports.PredicateActivityInterceptor = PredicateActivityInterceptor;
88
+ exports.PredicateAuthorizationError = PredicateAuthorizationError;
89
+ exports.createPredicateInterceptors = createPredicateInterceptors;
90
+ //# sourceMappingURL=index.js.map
91
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/interceptor.ts"],"names":["createHash"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error thrown when Predicate Authority denies an activity execution.\n */\nexport class PredicateAuthorizationError extends Error {\n /** The authorization reason code */\n public readonly reason: string;\n\n /** The policy rule that caused the denial, if any */\n public readonly violatedRule: string | undefined;\n\n /** Labels that were required but missing */\n public readonly missingLabels: readonly string[];\n\n /** The activity type that was denied */\n public readonly activityType: string;\n\n constructor(options: {\n activityType: string;\n reason: string;\n violatedRule?: string | undefined;\n missingLabels?: readonly string[];\n }) {\n const message = `Predicate Zero-Trust Denial: Activity '${options.activityType}' not authorized. Reason: ${options.reason}${\n options.violatedRule ? `, violated rule: ${options.violatedRule}` : \"\"\n }`;\n super(message);\n this.name = \"PredicateAuthorizationError\";\n this.reason = options.reason;\n this.violatedRule = options.violatedRule;\n this.missingLabels = options.missingLabels ?? [];\n this.activityType = options.activityType;\n }\n}\n","/**\n * Predicate Authority interceptor for Temporal.io activities.\n *\n * This module provides a pre-execution security gate for all Temporal Activities,\n * enforcing cryptographic authorization mandates before any activity code runs.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { Context } from \"@temporalio/activity\";\nimport type {\n ActivityExecuteInput,\n ActivityInboundCallsInterceptor,\n ActivityInterceptorsFactory,\n Next,\n WorkerInterceptors,\n} from \"@temporalio/worker\";\nimport { PredicateAuthorizationError } from \"./errors.js\";\n\n/**\n * Interface for the Predicate Authority client.\n * This matches the AuthorityClient from @predicatesystems/authority.\n */\nexport interface PredicateAuthorityClient {\n authorize(request: PredicateAuthorizeRequest): Promise<PredicateAuthorizationResponse>;\n}\n\n/**\n * Authorization request sent to the Predicate Authority sidecar.\n */\nexport interface PredicateAuthorizeRequest {\n principal: string;\n action: string;\n resource: string;\n intent_hash?: string;\n context?: Record<string, unknown>;\n labels?: string[];\n}\n\n/**\n * Authorization response from the Predicate Authority sidecar.\n */\nexport interface PredicateAuthorizationResponse {\n allowed: boolean;\n reason: string;\n mandate_id: string | null;\n violated_rule: string | null;\n missing_labels: string[];\n}\n\n/**\n * Options for creating Predicate interceptors.\n */\nexport interface PredicateInterceptorOptions {\n /** The Predicate Authority client for authorization */\n authorityClient: PredicateAuthorityClient;\n\n /** Principal ID used for authorization requests (default: \"temporal-worker\") */\n principal?: string;\n\n /** Optional tenant ID for multi-tenant setups */\n tenantId?: string;\n\n /** Optional session ID for request correlation */\n sessionId?: string;\n\n /** Optional resource identifier (default: \"temporal:activity\") */\n resource?: string;\n}\n\n/**\n * Activity interceptor that enforces Predicate Authority authorization.\n *\n * This interceptor sits in the Temporal activity execution pipeline and ensures\n * that every activity is authorized before execution. If authorization is denied,\n * a PredicateAuthorizationError is thrown and the activity never executes.\n */\nexport class PredicateActivityInterceptor implements ActivityInboundCallsInterceptor {\n private readonly authorityClient: PredicateAuthorityClient;\n private readonly principal: string;\n private readonly tenantId: string | undefined;\n private readonly sessionId: string | undefined;\n private readonly resource: string;\n private readonly activityType: string;\n\n constructor(ctx: Context, options: PredicateInterceptorOptions) {\n this.authorityClient = options.authorityClient;\n this.principal = options.principal ?? \"temporal-worker\";\n this.tenantId = options.tenantId;\n this.sessionId = options.sessionId;\n this.resource = options.resource ?? \"temporal:activity\";\n this.activityType = ctx.info.activityType;\n }\n\n /**\n * Execute activity with Predicate Authority authorization check.\n *\n * This method intercepts the activity execution, extracts the activity type\n * and arguments, and requests authorization from Predicate Authority.\n * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.\n */\n async execute(\n input: ActivityExecuteInput,\n next: Next<ActivityInboundCallsInterceptor, \"execute\">\n ): Promise<unknown> {\n const activityArgs = input.args;\n\n // Hash the arguments for state evidence\n const argsJson = JSON.stringify(activityArgs);\n const argsHash = createHash(\"sha256\").update(argsJson).digest(\"hex\");\n\n const request: PredicateAuthorizeRequest = {\n principal: this.principal,\n action: this.activityType,\n resource: this.resource,\n intent_hash: `ih_execute_${this.activityType.toLowerCase()}`,\n context: {\n state_hash: argsHash,\n tenant_id: this.tenantId,\n session_id: this.sessionId,\n },\n };\n\n const decision = await this.authorityClient.authorize(request);\n\n if (!decision.allowed) {\n throw new PredicateAuthorizationError({\n activityType: this.activityType,\n reason: decision.reason,\n violatedRule: decision.violated_rule ?? undefined,\n missingLabels: decision.missing_labels ?? [],\n });\n }\n\n return next(input);\n }\n}\n\n/**\n * Creates Temporal worker interceptors that enforce Predicate Authority authorization.\n *\n * @example\n * ```typescript\n * import { Worker } from \"@temporalio/worker\";\n * import { AuthorityClient } from \"@predicatesystems/authority\";\n * import { createPredicateInterceptors } from \"@predicatesystems/temporal\";\n *\n * const authorityClient = new AuthorityClient({\n * baseUrl: \"http://127.0.0.1:8787\",\n * });\n *\n * const interceptors = createPredicateInterceptors({\n * authorityClient,\n * principal: \"temporal-worker\",\n * });\n *\n * const worker = await Worker.create({\n * connection,\n * taskQueue: \"my-task-queue\",\n * workflowsPath: require.resolve(\"./workflows\"),\n * activities,\n * interceptors,\n * });\n * ```\n */\nexport function createPredicateInterceptors(\n options: PredicateInterceptorOptions\n): WorkerInterceptors {\n const activityInterceptorFactory: ActivityInterceptorsFactory = (ctx) => ({\n inbound: new PredicateActivityInterceptor(ctx, options),\n });\n\n return {\n activity: [activityInterceptorFactory],\n };\n}\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,87 @@
1
+ import { createHash } from 'crypto';
2
+
3
+ // src/interceptor.ts
4
+
5
+ // src/errors.ts
6
+ var PredicateAuthorizationError = class extends Error {
7
+ /** The authorization reason code */
8
+ reason;
9
+ /** The policy rule that caused the denial, if any */
10
+ violatedRule;
11
+ /** Labels that were required but missing */
12
+ missingLabels;
13
+ /** The activity type that was denied */
14
+ activityType;
15
+ constructor(options) {
16
+ const message = `Predicate Zero-Trust Denial: Activity '${options.activityType}' not authorized. Reason: ${options.reason}${options.violatedRule ? `, violated rule: ${options.violatedRule}` : ""}`;
17
+ super(message);
18
+ this.name = "PredicateAuthorizationError";
19
+ this.reason = options.reason;
20
+ this.violatedRule = options.violatedRule;
21
+ this.missingLabels = options.missingLabels ?? [];
22
+ this.activityType = options.activityType;
23
+ }
24
+ };
25
+
26
+ // src/interceptor.ts
27
+ var PredicateActivityInterceptor = class {
28
+ authorityClient;
29
+ principal;
30
+ tenantId;
31
+ sessionId;
32
+ resource;
33
+ activityType;
34
+ constructor(ctx, options) {
35
+ this.authorityClient = options.authorityClient;
36
+ this.principal = options.principal ?? "temporal-worker";
37
+ this.tenantId = options.tenantId;
38
+ this.sessionId = options.sessionId;
39
+ this.resource = options.resource ?? "temporal:activity";
40
+ this.activityType = ctx.info.activityType;
41
+ }
42
+ /**
43
+ * Execute activity with Predicate Authority authorization check.
44
+ *
45
+ * This method intercepts the activity execution, extracts the activity type
46
+ * and arguments, and requests authorization from Predicate Authority.
47
+ * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.
48
+ */
49
+ async execute(input, next) {
50
+ const activityArgs = input.args;
51
+ const argsJson = JSON.stringify(activityArgs);
52
+ const argsHash = createHash("sha256").update(argsJson).digest("hex");
53
+ const request = {
54
+ principal: this.principal,
55
+ action: this.activityType,
56
+ resource: this.resource,
57
+ intent_hash: `ih_execute_${this.activityType.toLowerCase()}`,
58
+ context: {
59
+ state_hash: argsHash,
60
+ tenant_id: this.tenantId,
61
+ session_id: this.sessionId
62
+ }
63
+ };
64
+ const decision = await this.authorityClient.authorize(request);
65
+ if (!decision.allowed) {
66
+ throw new PredicateAuthorizationError({
67
+ activityType: this.activityType,
68
+ reason: decision.reason,
69
+ violatedRule: decision.violated_rule ?? void 0,
70
+ missingLabels: decision.missing_labels ?? []
71
+ });
72
+ }
73
+ return next(input);
74
+ }
75
+ };
76
+ function createPredicateInterceptors(options) {
77
+ const activityInterceptorFactory = (ctx) => ({
78
+ inbound: new PredicateActivityInterceptor(ctx, options)
79
+ });
80
+ return {
81
+ activity: [activityInterceptorFactory]
82
+ };
83
+ }
84
+
85
+ export { PredicateActivityInterceptor, PredicateAuthorizationError, createPredicateInterceptors };
86
+ //# sourceMappingURL=index.mjs.map
87
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/interceptor.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Error thrown when Predicate Authority denies an activity execution.\n */\nexport class PredicateAuthorizationError extends Error {\n /** The authorization reason code */\n public readonly reason: string;\n\n /** The policy rule that caused the denial, if any */\n public readonly violatedRule: string | undefined;\n\n /** Labels that were required but missing */\n public readonly missingLabels: readonly string[];\n\n /** The activity type that was denied */\n public readonly activityType: string;\n\n constructor(options: {\n activityType: string;\n reason: string;\n violatedRule?: string | undefined;\n missingLabels?: readonly string[];\n }) {\n const message = `Predicate Zero-Trust Denial: Activity '${options.activityType}' not authorized. Reason: ${options.reason}${\n options.violatedRule ? `, violated rule: ${options.violatedRule}` : \"\"\n }`;\n super(message);\n this.name = \"PredicateAuthorizationError\";\n this.reason = options.reason;\n this.violatedRule = options.violatedRule;\n this.missingLabels = options.missingLabels ?? [];\n this.activityType = options.activityType;\n }\n}\n","/**\n * Predicate Authority interceptor for Temporal.io activities.\n *\n * This module provides a pre-execution security gate for all Temporal Activities,\n * enforcing cryptographic authorization mandates before any activity code runs.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { Context } from \"@temporalio/activity\";\nimport type {\n ActivityExecuteInput,\n ActivityInboundCallsInterceptor,\n ActivityInterceptorsFactory,\n Next,\n WorkerInterceptors,\n} from \"@temporalio/worker\";\nimport { PredicateAuthorizationError } from \"./errors.js\";\n\n/**\n * Interface for the Predicate Authority client.\n * This matches the AuthorityClient from @predicatesystems/authority.\n */\nexport interface PredicateAuthorityClient {\n authorize(request: PredicateAuthorizeRequest): Promise<PredicateAuthorizationResponse>;\n}\n\n/**\n * Authorization request sent to the Predicate Authority sidecar.\n */\nexport interface PredicateAuthorizeRequest {\n principal: string;\n action: string;\n resource: string;\n intent_hash?: string;\n context?: Record<string, unknown>;\n labels?: string[];\n}\n\n/**\n * Authorization response from the Predicate Authority sidecar.\n */\nexport interface PredicateAuthorizationResponse {\n allowed: boolean;\n reason: string;\n mandate_id: string | null;\n violated_rule: string | null;\n missing_labels: string[];\n}\n\n/**\n * Options for creating Predicate interceptors.\n */\nexport interface PredicateInterceptorOptions {\n /** The Predicate Authority client for authorization */\n authorityClient: PredicateAuthorityClient;\n\n /** Principal ID used for authorization requests (default: \"temporal-worker\") */\n principal?: string;\n\n /** Optional tenant ID for multi-tenant setups */\n tenantId?: string;\n\n /** Optional session ID for request correlation */\n sessionId?: string;\n\n /** Optional resource identifier (default: \"temporal:activity\") */\n resource?: string;\n}\n\n/**\n * Activity interceptor that enforces Predicate Authority authorization.\n *\n * This interceptor sits in the Temporal activity execution pipeline and ensures\n * that every activity is authorized before execution. If authorization is denied,\n * a PredicateAuthorizationError is thrown and the activity never executes.\n */\nexport class PredicateActivityInterceptor implements ActivityInboundCallsInterceptor {\n private readonly authorityClient: PredicateAuthorityClient;\n private readonly principal: string;\n private readonly tenantId: string | undefined;\n private readonly sessionId: string | undefined;\n private readonly resource: string;\n private readonly activityType: string;\n\n constructor(ctx: Context, options: PredicateInterceptorOptions) {\n this.authorityClient = options.authorityClient;\n this.principal = options.principal ?? \"temporal-worker\";\n this.tenantId = options.tenantId;\n this.sessionId = options.sessionId;\n this.resource = options.resource ?? \"temporal:activity\";\n this.activityType = ctx.info.activityType;\n }\n\n /**\n * Execute activity with Predicate Authority authorization check.\n *\n * This method intercepts the activity execution, extracts the activity type\n * and arguments, and requests authorization from Predicate Authority.\n * If denied, throws PredicateAuthorizationError. If approved, proceeds with execution.\n */\n async execute(\n input: ActivityExecuteInput,\n next: Next<ActivityInboundCallsInterceptor, \"execute\">\n ): Promise<unknown> {\n const activityArgs = input.args;\n\n // Hash the arguments for state evidence\n const argsJson = JSON.stringify(activityArgs);\n const argsHash = createHash(\"sha256\").update(argsJson).digest(\"hex\");\n\n const request: PredicateAuthorizeRequest = {\n principal: this.principal,\n action: this.activityType,\n resource: this.resource,\n intent_hash: `ih_execute_${this.activityType.toLowerCase()}`,\n context: {\n state_hash: argsHash,\n tenant_id: this.tenantId,\n session_id: this.sessionId,\n },\n };\n\n const decision = await this.authorityClient.authorize(request);\n\n if (!decision.allowed) {\n throw new PredicateAuthorizationError({\n activityType: this.activityType,\n reason: decision.reason,\n violatedRule: decision.violated_rule ?? undefined,\n missingLabels: decision.missing_labels ?? [],\n });\n }\n\n return next(input);\n }\n}\n\n/**\n * Creates Temporal worker interceptors that enforce Predicate Authority authorization.\n *\n * @example\n * ```typescript\n * import { Worker } from \"@temporalio/worker\";\n * import { AuthorityClient } from \"@predicatesystems/authority\";\n * import { createPredicateInterceptors } from \"@predicatesystems/temporal\";\n *\n * const authorityClient = new AuthorityClient({\n * baseUrl: \"http://127.0.0.1:8787\",\n * });\n *\n * const interceptors = createPredicateInterceptors({\n * authorityClient,\n * principal: \"temporal-worker\",\n * });\n *\n * const worker = await Worker.create({\n * connection,\n * taskQueue: \"my-task-queue\",\n * workflowsPath: require.resolve(\"./workflows\"),\n * activities,\n * interceptors,\n * });\n * ```\n */\nexport function createPredicateInterceptors(\n options: PredicateInterceptorOptions\n): WorkerInterceptors {\n const activityInterceptorFactory: ActivityInterceptorsFactory = (ctx) => ({\n inbound: new PredicateActivityInterceptor(ctx, options),\n });\n\n return {\n activity: [activityInterceptorFactory],\n };\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@predicatesystems/temporal",
3
+ "version": "0.1.0",
4
+ "description": "Temporal.io Worker Interceptor for Predicate Authority Zero-Trust authorization",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "dev": "tsup --watch",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:coverage": "vitest run --coverage",
26
+ "typecheck": "tsc --noEmit",
27
+ "lint": "biome check src tests",
28
+ "lint:fix": "biome check --write src tests",
29
+ "format": "biome format --write src tests",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "keywords": [
33
+ "temporal",
34
+ "temporalio",
35
+ "authorization",
36
+ "zero-trust",
37
+ "security",
38
+ "ai-agents",
39
+ "predicate-authority",
40
+ "interceptor"
41
+ ],
42
+ "author": "Predicate Systems <hello@predicatesystems.dev>",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/PredicateSystems/temporal-predicate-typescript.git"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/PredicateSystems/temporal-predicate-typescript/issues"
50
+ },
51
+ "homepage": "https://github.com/PredicateSystems/temporal-predicate-typescript#readme",
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "peerDependencies": {
56
+ "@predicatesystems/authority": ">=0.1.0",
57
+ "@temporalio/worker": ">=1.9.0"
58
+ },
59
+ "devDependencies": {
60
+ "@biomejs/biome": "^1.5.0",
61
+ "@predicatesystems/authority": "^0.3.0",
62
+ "@temporalio/worker": "^1.11.0",
63
+ "@types/node": "^20.11.0",
64
+ "@vitest/coverage-v8": "^1.2.0",
65
+ "tsup": "^8.0.0",
66
+ "typescript": "^5.3.0",
67
+ "vitest": "^1.2.0"
68
+ }
69
+ }