@naylence/advanced-security 0.4.4 → 0.4.6

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 (85) hide show
  1. package/dist/browser/index.cjs +702 -32
  2. package/dist/browser/index.mjs +702 -32
  3. package/dist/cjs/advanced-security-isomorphic.js +1 -1
  4. package/dist/cjs/advanced-security-isomorphic.js.map +1 -1
  5. package/dist/cjs/naylence/fame/expr/builtins.js +1 -1
  6. package/dist/cjs/naylence/fame/expr/builtins.js.map +1 -1
  7. package/dist/cjs/naylence/fame/factory-manifest.js +2 -0
  8. package/dist/cjs/naylence/fame/factory-manifest.js.map +1 -1
  9. package/dist/cjs/naylence/fame/security/auth/index.js +2 -0
  10. package/dist/cjs/naylence/fame/security/auth/index.js.map +1 -1
  11. package/dist/cjs/naylence/fame/security/auth/policy/advanced-authorization-policy.js +32 -13
  12. package/dist/cjs/naylence/fame/security/auth/policy/advanced-authorization-policy.js.map +1 -1
  13. package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server-cli.js +47 -0
  14. package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server-cli.js.map +1 -0
  15. package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server.js +553 -0
  16. package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server.js.map +1 -0
  17. package/dist/cjs/naylence/fame/security/auth/policy/expr-builtins.js +166 -2
  18. package/dist/cjs/naylence/fame/security/auth/policy/expr-builtins.js.map +1 -1
  19. package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js +108 -0
  20. package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js.map +1 -0
  21. package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source.js +367 -0
  22. package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source.js.map +1 -0
  23. package/dist/cjs/naylence/fame/security/auth/policy/index.js +4 -2
  24. package/dist/cjs/naylence/fame/security/auth/policy/index.js.map +1 -1
  25. package/dist/cjs/naylence/fame/security/auth/policy-http-authorization-profile.js +78 -0
  26. package/dist/cjs/naylence/fame/security/auth/policy-http-authorization-profile.js.map +1 -0
  27. package/dist/cjs/naylence/fame/security/register-advanced-security-factories.js +2 -0
  28. package/dist/cjs/naylence/fame/security/register-advanced-security-factories.js.map +1 -1
  29. package/dist/cjs/version.js +2 -2
  30. package/dist/esm/advanced-security-isomorphic.js +1 -1
  31. package/dist/esm/advanced-security-isomorphic.js.map +1 -1
  32. package/dist/esm/naylence/fame/expr/builtins.js +1 -1
  33. package/dist/esm/naylence/fame/expr/builtins.js.map +1 -1
  34. package/dist/esm/naylence/fame/factory-manifest.js +2 -0
  35. package/dist/esm/naylence/fame/factory-manifest.js.map +1 -1
  36. package/dist/esm/naylence/fame/security/auth/index.js +2 -0
  37. package/dist/esm/naylence/fame/security/auth/index.js.map +1 -1
  38. package/dist/esm/naylence/fame/security/auth/policy/advanced-authorization-policy.js +32 -13
  39. package/dist/esm/naylence/fame/security/auth/policy/advanced-authorization-policy.js.map +1 -1
  40. package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server-cli.js +47 -0
  41. package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server-cli.js.map +1 -0
  42. package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server.js +553 -0
  43. package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server.js.map +1 -0
  44. package/dist/esm/naylence/fame/security/auth/policy/expr-builtins.js +166 -2
  45. package/dist/esm/naylence/fame/security/auth/policy/expr-builtins.js.map +1 -1
  46. package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js +108 -0
  47. package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js.map +1 -0
  48. package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source.js +367 -0
  49. package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source.js.map +1 -0
  50. package/dist/esm/naylence/fame/security/auth/policy/index.js +4 -2
  51. package/dist/esm/naylence/fame/security/auth/policy/index.js.map +1 -1
  52. package/dist/esm/naylence/fame/security/auth/policy-http-authorization-profile.js +78 -0
  53. package/dist/esm/naylence/fame/security/auth/policy-http-authorization-profile.js.map +1 -0
  54. package/dist/esm/naylence/fame/security/register-advanced-security-factories.js +2 -0
  55. package/dist/esm/naylence/fame/security/register-advanced-security-factories.js.map +1 -1
  56. package/dist/esm/version.js +2 -2
  57. package/dist/node/index.cjs +777 -139
  58. package/dist/node/index.mjs +770 -109
  59. package/dist/node/node.cjs +788 -65
  60. package/dist/node/node.mjs +780 -34
  61. package/dist/types/advanced-security-isomorphic.d.ts +0 -1
  62. package/dist/types/advanced-security-isomorphic.d.ts.map +1 -1
  63. package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
  64. package/dist/types/naylence/fame/factory-manifest.d.ts.map +1 -1
  65. package/dist/types/naylence/fame/security/auth/index.d.ts +1 -0
  66. package/dist/types/naylence/fame/security/auth/index.d.ts.map +1 -1
  67. package/dist/types/naylence/fame/security/auth/policy/advanced-authorization-policy.d.ts.map +1 -1
  68. package/dist/types/naylence/fame/security/auth/policy/auth-policy-server-cli.d.ts +20 -0
  69. package/dist/types/naylence/fame/security/auth/policy/auth-policy-server-cli.d.ts.map +1 -0
  70. package/dist/types/naylence/fame/security/auth/policy/auth-policy-server.d.ts +74 -0
  71. package/dist/types/naylence/fame/security/auth/policy/auth-policy-server.d.ts.map +1 -0
  72. package/dist/types/naylence/fame/security/auth/policy/expr-builtins.d.ts +71 -1
  73. package/dist/types/naylence/fame/security/auth/policy/expr-builtins.d.ts.map +1 -1
  74. package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.d.ts +81 -0
  75. package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.d.ts.map +1 -0
  76. package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source.d.ts +150 -0
  77. package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source.d.ts.map +1 -0
  78. package/dist/types/naylence/fame/security/auth/policy/index.d.ts +2 -1
  79. package/dist/types/naylence/fame/security/auth/policy/index.d.ts.map +1 -1
  80. package/dist/types/naylence/fame/security/auth/policy-http-authorization-profile.d.ts +17 -0
  81. package/dist/types/naylence/fame/security/auth/policy-http-authorization-profile.d.ts.map +1 -0
  82. package/dist/types/naylence/fame/security/register-advanced-security-factories.d.ts +1 -0
  83. package/dist/types/naylence/fame/security/register-advanced-security-factories.d.ts.map +1 -1
  84. package/dist/types/version.d.ts +1 -1
  85. package/package.json +3 -2
@@ -0,0 +1,553 @@
1
+ /**
2
+ * Auth Policy Server - Authorization Policy HTTP endpoint
3
+ *
4
+ * Provides authorization policies via HTTP using Fastify.
5
+ * Supports OAuth2 JWT authentication and ETag-based caching.
6
+ * Serves multiple policies by ID from a configurable directory.
7
+ * This is a development server for testing HTTP policy source functionality.
8
+ *
9
+ * Policy files should be named: policy-{policy_id}.yaml or policy-{policy_id}.json
10
+ * Example: policy-production.yaml, policy-dev.json
11
+ *
12
+ * Authentication:
13
+ * - Set FAME_OAUTH2_ISSUER to enable OAuth2 JWT validation
14
+ * - Optionally set FAME_OAUTH2_AUDIENCE, FAME_OAUTH2_JWKS_URL
15
+ * - If no OAuth2 config provided, authentication is disabled (dev mode)
16
+ */
17
+ import { createHash } from "node:crypto";
18
+ import Fastify from "fastify";
19
+ import { realpathSync, readFileSync, existsSync, statSync, readdirSync, watch, } from "node:fs";
20
+ import { resolve, extname, join } from "node:path";
21
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
22
+ // Simple console logger for policy server
23
+ const logger = {
24
+ info: (event, meta) => {
25
+ console.log(`[INFO] ${event}`, meta || "");
26
+ },
27
+ warning: (event, meta) => {
28
+ console.warn(`[WARNING] ${event}`, meta || "");
29
+ },
30
+ error: (event, meta) => {
31
+ console.error(`[ERROR] ${event}`, meta || "");
32
+ },
33
+ debug: (event, meta) => {
34
+ const logLevel = (process.env.FAME_LOG_LEVEL || "info").toLowerCase();
35
+ if (logLevel === "debug" || logLevel === "trace") {
36
+ console.log(`[DEBUG] ${event}`, meta || "");
37
+ }
38
+ },
39
+ };
40
+ // Environment variables
41
+ const ENV_VAR_FAME_APP_HOST = "FAME_APP_HOST";
42
+ const ENV_VAR_FAME_APP_PORT = "FAME_APP_PORT";
43
+ const ENV_VAR_FAME_POLICY_DIR = "FAME_POLICY_DIR";
44
+ // OAuth2 configuration
45
+ const ENV_VAR_OAUTH2_ISSUER = "FAME_OAUTH2_ISSUER";
46
+ const ENV_VAR_OAUTH2_AUDIENCE = "FAME_OAUTH2_AUDIENCE";
47
+ const ENV_VAR_OAUTH2_JWKS_URL = "FAME_OAUTH2_JWKS_URL";
48
+ const ENV_VAR_OAUTH2_REQUIRED_SCOPES = "FAME_OAUTH2_REQUIRED_SCOPES";
49
+ // Policy file naming pattern: policy-{id}.yaml or policy-{id}.json
50
+ const POLICY_FILE_PATTERN = /^policy-(.+)\.(ya?ml|json)$/i;
51
+ /**
52
+ * Default authorization policy for development.
53
+ * Allows all operations - suitable for testing only.
54
+ */
55
+ const DEFAULT_POLICY = {
56
+ version: "1",
57
+ type: "AdvancedAuthorizationPolicy",
58
+ default_effect: "deny",
59
+ rules: [
60
+ {
61
+ id: "allow-all-dev",
62
+ effect: "allow",
63
+ comment: "Development policy - allows all operations",
64
+ },
65
+ ],
66
+ };
67
+ /**
68
+ * Compute ETag from content using SHA-256.
69
+ */
70
+ function computeEtag(content) {
71
+ const hash = createHash("sha256");
72
+ hash.update(content, "utf-8");
73
+ return `"${hash.digest("hex").substring(0, 16)}"`;
74
+ }
75
+ /**
76
+ * Extract policy ID from filename.
77
+ * Expected format: policy-{id}.yaml or policy-{id}.json
78
+ */
79
+ function extractPolicyId(filename) {
80
+ const match = POLICY_FILE_PATTERN.exec(filename);
81
+ if (!match) {
82
+ return null;
83
+ }
84
+ const id = match[1];
85
+ const ext = match[2]?.toLowerCase();
86
+ const format = ext === "json" ? "json" : "yaml";
87
+ return { id, format };
88
+ }
89
+ /**
90
+ * Load a single policy from file.
91
+ */
92
+ function loadPolicyFile(filePath) {
93
+ try {
94
+ const content = readFileSync(filePath, "utf-8");
95
+ const ext = extname(filePath).toLowerCase();
96
+ let policy;
97
+ if (ext === ".json") {
98
+ policy = JSON.parse(content);
99
+ }
100
+ else {
101
+ policy = parseYaml(content);
102
+ }
103
+ const stats = statSync(filePath);
104
+ const format = ext === ".json" ? "json" : "yaml";
105
+ return {
106
+ policy,
107
+ policyContent: content,
108
+ etag: computeEtag(content),
109
+ lastModified: stats.mtime,
110
+ filePath,
111
+ format,
112
+ };
113
+ }
114
+ catch (error) {
115
+ logger.error("policy_file_load_error", {
116
+ path: filePath,
117
+ error: error instanceof Error ? error.message : String(error),
118
+ });
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * Load all policies from a directory.
124
+ */
125
+ function loadPoliciesFromDir(dirPath) {
126
+ const policies = new Map();
127
+ if (!existsSync(dirPath)) {
128
+ logger.warning("policy_directory_not_found", { path: dirPath });
129
+ return policies;
130
+ }
131
+ const files = readdirSync(dirPath);
132
+ for (const filename of files) {
133
+ const parsed = extractPolicyId(filename);
134
+ if (!parsed) {
135
+ continue;
136
+ }
137
+ const filePath = join(dirPath, filename);
138
+ const entry = loadPolicyFile(filePath);
139
+ if (entry) {
140
+ policies.set(parsed.id, {
141
+ id: parsed.id,
142
+ ...entry,
143
+ });
144
+ logger.info("policy_loaded", { id: parsed.id, path: filePath });
145
+ }
146
+ }
147
+ return policies;
148
+ }
149
+ /**
150
+ * Create default policy entry.
151
+ */
152
+ function createDefaultPolicyEntry() {
153
+ const content = JSON.stringify(DEFAULT_POLICY, null, 2);
154
+ return {
155
+ id: "default",
156
+ policy: DEFAULT_POLICY,
157
+ policyContent: content,
158
+ etag: computeEtag(content),
159
+ lastModified: new Date(),
160
+ filePath: "(built-in)",
161
+ format: "json",
162
+ };
163
+ }
164
+ /**
165
+ * Create an OAuth2 token verifier from environment configuration.
166
+ */
167
+ async function createTokenVerifier() {
168
+ const issuer = process.env[ENV_VAR_OAUTH2_ISSUER];
169
+ if (!issuer) {
170
+ return null;
171
+ }
172
+ try {
173
+ // Dynamically import the token verifier factory from @naylence/runtime
174
+ const { TokenVerifierFactory } = await import("@naylence/runtime");
175
+ const jwksUrl = process.env[ENV_VAR_OAUTH2_JWKS_URL] ||
176
+ `${issuer.replace(/\/+$/, "")}/.well-known/jwks.json`;
177
+ const config = {
178
+ type: "JWKSJWTTokenVerifier",
179
+ issuer,
180
+ jwks_url: jwksUrl,
181
+ algorithms: ["RS256"],
182
+ };
183
+ const audience = process.env[ENV_VAR_OAUTH2_AUDIENCE];
184
+ if (audience) {
185
+ config.audience = audience;
186
+ }
187
+ const verifier = await TokenVerifierFactory.createTokenVerifier(config);
188
+ logger.info("oauth2_token_verifier_created", { issuer, jwksUrl });
189
+ return verifier;
190
+ }
191
+ catch (error) {
192
+ logger.error("failed_to_create_token_verifier", {
193
+ error: error instanceof Error ? error.message : String(error),
194
+ });
195
+ return null;
196
+ }
197
+ }
198
+ /**
199
+ * Authenticate request using OAuth2 JWT verification.
200
+ */
201
+ async function authenticateRequest(request, tokenVerifier) {
202
+ if (!tokenVerifier) {
203
+ // No auth required (dev mode)
204
+ return { authenticated: true };
205
+ }
206
+ const authHeader = request.headers.authorization;
207
+ if (!authHeader) {
208
+ return { authenticated: false, error: "Missing Authorization header" };
209
+ }
210
+ const parts = authHeader.split(" ");
211
+ if (parts.length !== 2 || parts[0]?.toLowerCase() !== "bearer") {
212
+ return { authenticated: false, error: "Invalid Authorization header format" };
213
+ }
214
+ const token = parts[1];
215
+ if (!token) {
216
+ return { authenticated: false, error: "Missing bearer token" };
217
+ }
218
+ try {
219
+ const claims = await tokenVerifier.verify(token);
220
+ // Check required scopes if configured
221
+ const requiredScopesEnv = process.env[ENV_VAR_OAUTH2_REQUIRED_SCOPES];
222
+ if (requiredScopesEnv) {
223
+ const requiredScopes = requiredScopesEnv.split(",").map((s) => s.trim());
224
+ const tokenScopes = typeof claims.scope === "string"
225
+ ? claims.scope.split(" ")
226
+ : Array.isArray(claims.scp)
227
+ ? claims.scp
228
+ : [];
229
+ const hasAllScopes = requiredScopes.every((required) => tokenScopes.includes(required));
230
+ if (!hasAllScopes) {
231
+ return {
232
+ authenticated: false,
233
+ error: `Missing required scopes: ${requiredScopes.join(", ")}`,
234
+ };
235
+ }
236
+ }
237
+ logger.debug("jwt_token_verified", { sub: claims.sub });
238
+ return { authenticated: true, claims };
239
+ }
240
+ catch (error) {
241
+ logger.warning("jwt_verification_failed", {
242
+ error: error instanceof Error ? error.message : String(error),
243
+ });
244
+ return {
245
+ authenticated: false,
246
+ error: error instanceof Error ? error.message : "Token verification failed",
247
+ };
248
+ }
249
+ }
250
+ /**
251
+ * Create policy router with authorization policy endpoints.
252
+ * Supports fetching policies by ID from: /fame/v1/auth-policies/:policyId
253
+ */
254
+ function createPolicyRouter(fastify, state, tokenVerifier, prefix = "/fame/v1") {
255
+ const policiesPath = `${prefix}/auth-policies`;
256
+ // List all available policies
257
+ fastify.get(policiesPath, async (request, reply) => {
258
+ const authResult = await authenticateRequest(request, tokenVerifier);
259
+ if (!authResult.authenticated) {
260
+ logger.warning("authentication_failed", { error: authResult.error });
261
+ return reply.status(401).send({
262
+ error: "unauthorized",
263
+ message: authResult.error,
264
+ });
265
+ }
266
+ const policyList = Array.from(state.policies.values()).map((entry) => ({
267
+ id: entry.id,
268
+ lastModified: entry.lastModified.toISOString(),
269
+ format: entry.format,
270
+ }));
271
+ return reply
272
+ .header("Content-Type", "application/json")
273
+ .send({ policies: policyList });
274
+ });
275
+ // Get policy by ID (auto-detect format based on Accept header or original format)
276
+ fastify.get(`${policiesPath}/:policyId`, async (request, reply) => {
277
+ const authResult = await authenticateRequest(request, tokenVerifier);
278
+ if (!authResult.authenticated) {
279
+ logger.warning("authentication_failed", { error: authResult.error });
280
+ return reply.status(401).send({
281
+ error: "unauthorized",
282
+ message: authResult.error,
283
+ });
284
+ }
285
+ const { policyId } = request.params;
286
+ const entry = state.policies.get(policyId);
287
+ if (!entry) {
288
+ logger.warning("policy_not_found", { policyId });
289
+ return reply.status(404).send({
290
+ error: "not_found",
291
+ message: `Policy '${policyId}' not found`,
292
+ availablePolicies: Array.from(state.policies.keys()),
293
+ });
294
+ }
295
+ // Check ETag for conditional request
296
+ const ifNoneMatch = request.headers["if-none-match"];
297
+ if (ifNoneMatch && ifNoneMatch === entry.etag) {
298
+ logger.debug("returning_304_not_modified", { policyId, etag: entry.etag });
299
+ return reply
300
+ .status(304)
301
+ .header("ETag", entry.etag)
302
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
303
+ .send();
304
+ }
305
+ logger.debug("serving_policy", {
306
+ policyId,
307
+ etag: entry.etag,
308
+ lastModified: entry.lastModified.toISOString(),
309
+ });
310
+ // Determine content type based on Accept header or original format
311
+ const acceptHeader = request.headers.accept || "";
312
+ const isYamlRequest = acceptHeader.includes("yaml") || acceptHeader.includes("text/plain");
313
+ let contentType;
314
+ let responseBody;
315
+ if (isYamlRequest || entry.format === "yaml") {
316
+ contentType = "application/yaml";
317
+ responseBody =
318
+ entry.format === "yaml"
319
+ ? entry.policyContent
320
+ : stringifyYaml(entry.policy);
321
+ }
322
+ else {
323
+ contentType = "application/json";
324
+ responseBody = JSON.stringify(entry.policy, null, 2);
325
+ }
326
+ return reply
327
+ .header("Content-Type", contentType)
328
+ .header("ETag", entry.etag)
329
+ .header("Last-Modified", entry.lastModified.toUTCString())
330
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
331
+ .send(responseBody);
332
+ });
333
+ // Get policy by ID as YAML
334
+ fastify.get(`${policiesPath}/:policyId.yaml`, async (request, reply) => {
335
+ const authResult = await authenticateRequest(request, tokenVerifier);
336
+ if (!authResult.authenticated) {
337
+ return reply.status(401).send({
338
+ error: "unauthorized",
339
+ message: authResult.error,
340
+ });
341
+ }
342
+ const { policyId } = request.params;
343
+ const entry = state.policies.get(policyId);
344
+ if (!entry) {
345
+ return reply.status(404).send({
346
+ error: "not_found",
347
+ message: `Policy '${policyId}' not found`,
348
+ });
349
+ }
350
+ const ifNoneMatch = request.headers["if-none-match"];
351
+ if (ifNoneMatch && ifNoneMatch === entry.etag) {
352
+ return reply
353
+ .status(304)
354
+ .header("ETag", entry.etag)
355
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
356
+ .send();
357
+ }
358
+ const yamlContent = entry.format === "yaml" ? entry.policyContent : stringifyYaml(entry.policy);
359
+ return reply
360
+ .header("Content-Type", "application/yaml")
361
+ .header("ETag", entry.etag)
362
+ .header("Last-Modified", entry.lastModified.toUTCString())
363
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
364
+ .send(yamlContent);
365
+ });
366
+ // Get policy by ID as JSON
367
+ fastify.get(`${policiesPath}/:policyId.json`, async (request, reply) => {
368
+ const authResult = await authenticateRequest(request, tokenVerifier);
369
+ if (!authResult.authenticated) {
370
+ return reply.status(401).send({
371
+ error: "unauthorized",
372
+ message: authResult.error,
373
+ });
374
+ }
375
+ const { policyId } = request.params;
376
+ const entry = state.policies.get(policyId);
377
+ if (!entry) {
378
+ return reply.status(404).send({
379
+ error: "not_found",
380
+ message: `Policy '${policyId}' not found`,
381
+ });
382
+ }
383
+ const ifNoneMatch = request.headers["if-none-match"];
384
+ if (ifNoneMatch && ifNoneMatch === entry.etag) {
385
+ return reply
386
+ .status(304)
387
+ .header("ETag", entry.etag)
388
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
389
+ .send();
390
+ }
391
+ return reply
392
+ .header("Content-Type", "application/json")
393
+ .header("ETag", entry.etag)
394
+ .header("Last-Modified", entry.lastModified.toUTCString())
395
+ .header("Cache-Control", "public, max-age=60, stale-while-revalidate=300")
396
+ .send(entry.policy);
397
+ });
398
+ // Health check
399
+ fastify.get("/health", async () => {
400
+ return {
401
+ status: "healthy",
402
+ service: "auth-policy-server",
403
+ policyDirectory: state.policyDir || "(using defaults)",
404
+ policyCount: state.policies.size,
405
+ policies: Array.from(state.policies.keys()),
406
+ };
407
+ });
408
+ }
409
+ /**
410
+ * Create Fastify application with policy server.
411
+ */
412
+ async function createApp() {
413
+ const fastify = Fastify({
414
+ logger: false,
415
+ });
416
+ // Load policies from directory or use default
417
+ const policyDir = process.env[ENV_VAR_FAME_POLICY_DIR];
418
+ const state = {
419
+ policyDir,
420
+ policies: new Map(),
421
+ };
422
+ if (policyDir && existsSync(policyDir)) {
423
+ state.policies = loadPoliciesFromDir(policyDir);
424
+ // Watch directory for changes
425
+ watch(policyDir, (eventType, filename) => {
426
+ if (!filename)
427
+ return;
428
+ const parsed = extractPolicyId(filename);
429
+ if (!parsed)
430
+ return;
431
+ const filePath = join(policyDir, filename);
432
+ if (eventType === "rename") {
433
+ // File added or removed
434
+ if (existsSync(filePath)) {
435
+ const entry = loadPolicyFile(filePath);
436
+ if (entry) {
437
+ state.policies.set(parsed.id, { id: parsed.id, ...entry });
438
+ logger.info("policy_added", { id: parsed.id, path: filePath });
439
+ }
440
+ }
441
+ else {
442
+ state.policies.delete(parsed.id);
443
+ logger.info("policy_removed", { id: parsed.id });
444
+ }
445
+ }
446
+ else if (eventType === "change") {
447
+ // File modified
448
+ const entry = loadPolicyFile(filePath);
449
+ if (entry) {
450
+ state.policies.set(parsed.id, { id: parsed.id, ...entry });
451
+ logger.info("policy_reloaded", { id: parsed.id, path: filePath });
452
+ }
453
+ }
454
+ });
455
+ logger.info("watching_policy_directory", { path: policyDir });
456
+ }
457
+ // Always add a default policy
458
+ if (state.policies.size === 0) {
459
+ state.policies.set("default", createDefaultPolicyEntry());
460
+ logger.info("using_default_policy", {
461
+ reason: policyDir ? "no_policies_found_in_directory" : "no_directory_specified",
462
+ });
463
+ }
464
+ // Create OAuth2 token verifier if configured
465
+ const tokenVerifier = await createTokenVerifier();
466
+ // Register policy router
467
+ createPolicyRouter(fastify, state, tokenVerifier);
468
+ if (tokenVerifier) {
469
+ logger.info("oauth2_jwt_auth_enabled", {
470
+ issuer: process.env[ENV_VAR_OAUTH2_ISSUER],
471
+ });
472
+ }
473
+ else {
474
+ logger.warning("auth_disabled", {
475
+ message: "Set FAME_OAUTH2_ISSUER to enable OAuth2 JWT authentication",
476
+ });
477
+ }
478
+ return { app: fastify, state };
479
+ }
480
+ async function main() {
481
+ try {
482
+ const { app, state } = await createApp();
483
+ const host = process.env[ENV_VAR_FAME_APP_HOST] || "0.0.0.0";
484
+ const port = parseInt(process.env[ENV_VAR_FAME_APP_PORT] || "8099", 10);
485
+ await app.listen({ host, port });
486
+ const issuer = process.env[ENV_VAR_OAUTH2_ISSUER];
487
+ logger.info("auth_policy_server_started", { host, port });
488
+ console.log(`\nšŸ“ Auth Policy Server listening on http://${host}:${port}`);
489
+ console.log(`šŸ“‹ List policies: http://${host}:${port}/fame/v1/auth-policies`);
490
+ console.log(`šŸ“‹ Get policy: http://${host}:${port}/fame/v1/auth-policies/{policy_id}`);
491
+ console.log(`šŸ“‹ Get as YAML: http://${host}:${port}/fame/v1/auth-policies/{policy_id}.yaml`);
492
+ console.log(`šŸ“‹ Get as JSON: http://${host}:${port}/fame/v1/auth-policies/{policy_id}.json`);
493
+ console.log(`šŸ” Health check: http://${host}:${port}/health`);
494
+ if (state.policyDir) {
495
+ console.log(`šŸ“ Serving policies from: ${state.policyDir}`);
496
+ console.log(`šŸ“ Policy files should be named: policy-{id}.yaml or policy-{id}.json`);
497
+ }
498
+ else {
499
+ console.log(`āš ļø No policy directory set (set FAME_POLICY_DIR to serve custom policies)`);
500
+ }
501
+ console.log(`šŸ“Š Loaded ${state.policies.size} policy(ies): ${Array.from(state.policies.keys()).join(", ")}`);
502
+ if (issuer) {
503
+ console.log(`šŸ” OAuth2 JWT authentication enabled (issuer: ${issuer})`);
504
+ }
505
+ else {
506
+ console.log(`āš ļø No authentication (set FAME_OAUTH2_ISSUER to enable)`);
507
+ }
508
+ console.log("");
509
+ }
510
+ catch (error) {
511
+ logger.error("auth_policy_server_startup_failed", {
512
+ error: error instanceof Error ? error.message : String(error),
513
+ });
514
+ process.exit(1);
515
+ }
516
+ }
517
+ export { createApp, main, loadPoliciesFromDir, loadPolicyFile, extractPolicyId, computeEtag, DEFAULT_POLICY, };
518
+ const isTopLevelInvocation = (() => {
519
+ if (typeof process === "undefined") {
520
+ return false;
521
+ }
522
+ const entry = process.argv[1] ?? null;
523
+ if (!entry) {
524
+ return false;
525
+ }
526
+ try {
527
+ const entryPath = resolveToRealPath(entry);
528
+ if (!entryPath) {
529
+ return false;
530
+ }
531
+ return /(?:^|[\\/])auth-policy-server\.js$/u.test(entryPath);
532
+ }
533
+ catch {
534
+ return false;
535
+ }
536
+ })();
537
+ if (isTopLevelInvocation) {
538
+ void main();
539
+ }
540
+ function resolveToRealPath(pathLike) {
541
+ try {
542
+ return realpathSync(pathLike);
543
+ }
544
+ catch {
545
+ try {
546
+ return realpathSync.native?.(pathLike) ?? resolve(pathLike);
547
+ }
548
+ catch {
549
+ return resolve(pathLike);
550
+ }
551
+ }
552
+ }
553
+ //# sourceMappingURL=auth-policy-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-policy-server.js","sourceRoot":"","sources":["../../../../../../../src/naylence/fame/security/auth/policy/auth-policy-server.ts"],"names":[],"mappings":"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"}