@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.
- package/dist/browser/index.cjs +702 -32
- package/dist/browser/index.mjs +702 -32
- package/dist/cjs/advanced-security-isomorphic.js +1 -1
- package/dist/cjs/advanced-security-isomorphic.js.map +1 -1
- package/dist/cjs/naylence/fame/expr/builtins.js +1 -1
- package/dist/cjs/naylence/fame/expr/builtins.js.map +1 -1
- package/dist/cjs/naylence/fame/factory-manifest.js +2 -0
- package/dist/cjs/naylence/fame/factory-manifest.js.map +1 -1
- package/dist/cjs/naylence/fame/security/auth/index.js +2 -0
- package/dist/cjs/naylence/fame/security/auth/index.js.map +1 -1
- package/dist/cjs/naylence/fame/security/auth/policy/advanced-authorization-policy.js +32 -13
- package/dist/cjs/naylence/fame/security/auth/policy/advanced-authorization-policy.js.map +1 -1
- package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server-cli.js +47 -0
- package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server-cli.js.map +1 -0
- package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server.js +553 -0
- package/dist/cjs/naylence/fame/security/auth/policy/auth-policy-server.js.map +1 -0
- package/dist/cjs/naylence/fame/security/auth/policy/expr-builtins.js +166 -2
- package/dist/cjs/naylence/fame/security/auth/policy/expr-builtins.js.map +1 -1
- package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js +108 -0
- package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js.map +1 -0
- package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source.js +367 -0
- package/dist/cjs/naylence/fame/security/auth/policy/http-authorization-policy-source.js.map +1 -0
- package/dist/cjs/naylence/fame/security/auth/policy/index.js +4 -2
- package/dist/cjs/naylence/fame/security/auth/policy/index.js.map +1 -1
- package/dist/cjs/naylence/fame/security/auth/policy-http-authorization-profile.js +78 -0
- package/dist/cjs/naylence/fame/security/auth/policy-http-authorization-profile.js.map +1 -0
- package/dist/cjs/naylence/fame/security/register-advanced-security-factories.js +2 -0
- package/dist/cjs/naylence/fame/security/register-advanced-security-factories.js.map +1 -1
- package/dist/cjs/version.js +2 -2
- package/dist/esm/advanced-security-isomorphic.js +1 -1
- package/dist/esm/advanced-security-isomorphic.js.map +1 -1
- package/dist/esm/naylence/fame/expr/builtins.js +1 -1
- package/dist/esm/naylence/fame/expr/builtins.js.map +1 -1
- package/dist/esm/naylence/fame/factory-manifest.js +2 -0
- package/dist/esm/naylence/fame/factory-manifest.js.map +1 -1
- package/dist/esm/naylence/fame/security/auth/index.js +2 -0
- package/dist/esm/naylence/fame/security/auth/index.js.map +1 -1
- package/dist/esm/naylence/fame/security/auth/policy/advanced-authorization-policy.js +32 -13
- package/dist/esm/naylence/fame/security/auth/policy/advanced-authorization-policy.js.map +1 -1
- package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server-cli.js +47 -0
- package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server-cli.js.map +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server.js +553 -0
- package/dist/esm/naylence/fame/security/auth/policy/auth-policy-server.js.map +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/expr-builtins.js +166 -2
- package/dist/esm/naylence/fame/security/auth/policy/expr-builtins.js.map +1 -1
- package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js +108 -0
- package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.js.map +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source.js +367 -0
- package/dist/esm/naylence/fame/security/auth/policy/http-authorization-policy-source.js.map +1 -0
- package/dist/esm/naylence/fame/security/auth/policy/index.js +4 -2
- package/dist/esm/naylence/fame/security/auth/policy/index.js.map +1 -1
- package/dist/esm/naylence/fame/security/auth/policy-http-authorization-profile.js +78 -0
- package/dist/esm/naylence/fame/security/auth/policy-http-authorization-profile.js.map +1 -0
- package/dist/esm/naylence/fame/security/register-advanced-security-factories.js +2 -0
- package/dist/esm/naylence/fame/security/register-advanced-security-factories.js.map +1 -1
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +777 -139
- package/dist/node/index.mjs +770 -109
- package/dist/node/node.cjs +788 -65
- package/dist/node/node.mjs +780 -34
- package/dist/types/advanced-security-isomorphic.d.ts +0 -1
- package/dist/types/advanced-security-isomorphic.d.ts.map +1 -1
- package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
- package/dist/types/naylence/fame/factory-manifest.d.ts.map +1 -1
- package/dist/types/naylence/fame/security/auth/index.d.ts +1 -0
- package/dist/types/naylence/fame/security/auth/index.d.ts.map +1 -1
- package/dist/types/naylence/fame/security/auth/policy/advanced-authorization-policy.d.ts.map +1 -1
- package/dist/types/naylence/fame/security/auth/policy/auth-policy-server-cli.d.ts +20 -0
- package/dist/types/naylence/fame/security/auth/policy/auth-policy-server-cli.d.ts.map +1 -0
- package/dist/types/naylence/fame/security/auth/policy/auth-policy-server.d.ts +74 -0
- package/dist/types/naylence/fame/security/auth/policy/auth-policy-server.d.ts.map +1 -0
- package/dist/types/naylence/fame/security/auth/policy/expr-builtins.d.ts +71 -1
- package/dist/types/naylence/fame/security/auth/policy/expr-builtins.d.ts.map +1 -1
- package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.d.ts +81 -0
- package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source-factory.d.ts.map +1 -0
- package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source.d.ts +150 -0
- package/dist/types/naylence/fame/security/auth/policy/http-authorization-policy-source.d.ts.map +1 -0
- package/dist/types/naylence/fame/security/auth/policy/index.d.ts +2 -1
- package/dist/types/naylence/fame/security/auth/policy/index.d.ts.map +1 -1
- package/dist/types/naylence/fame/security/auth/policy-http-authorization-profile.d.ts +17 -0
- package/dist/types/naylence/fame/security/auth/policy-http-authorization-profile.d.ts.map +1 -0
- package/dist/types/naylence/fame/security/register-advanced-security-factories.d.ts +1 -0
- package/dist/types/naylence/fame/security/register-advanced-security-factories.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- 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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"}
|