zeroauth 1.0.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.
Files changed (64) hide show
  1. package/dist/api/authorizer.d.ts +12 -0
  2. package/dist/api/authorizer.d.ts.map +1 -0
  3. package/dist/api/authorizer.js +157 -0
  4. package/dist/api/authorizer.js.map +1 -0
  5. package/dist/api/config/intent-config.d.ts +45 -0
  6. package/dist/api/config/intent-config.d.ts.map +1 -0
  7. package/dist/api/config/intent-config.js +95 -0
  8. package/dist/api/config/intent-config.js.map +1 -0
  9. package/dist/api/index.d.ts +4 -0
  10. package/dist/api/index.d.ts.map +1 -0
  11. package/dist/api/index.js +722 -0
  12. package/dist/api/index.js.map +1 -0
  13. package/dist/api/routing/intent-router.d.ts +56 -0
  14. package/dist/api/routing/intent-router.d.ts.map +1 -0
  15. package/dist/api/routing/intent-router.js +140 -0
  16. package/dist/api/routing/intent-router.js.map +1 -0
  17. package/dist/api/routing/intent-validator.d.ts +83 -0
  18. package/dist/api/routing/intent-validator.d.ts.map +1 -0
  19. package/dist/api/routing/intent-validator.js +187 -0
  20. package/dist/api/routing/intent-validator.js.map +1 -0
  21. package/dist/api/services/billing.d.ts +9 -0
  22. package/dist/api/services/billing.d.ts.map +1 -0
  23. package/dist/api/services/billing.js +49 -0
  24. package/dist/api/services/billing.js.map +1 -0
  25. package/dist/api/services/stripe.d.ts +17 -0
  26. package/dist/api/services/stripe.d.ts.map +1 -0
  27. package/dist/api/services/stripe.js +69 -0
  28. package/dist/api/services/stripe.js.map +1 -0
  29. package/dist/authorizer.zip +0 -0
  30. package/dist/cli/auth.d.ts +20 -0
  31. package/dist/cli/auth.d.ts.map +1 -0
  32. package/dist/cli/auth.js +264 -0
  33. package/dist/cli/auth.js.map +1 -0
  34. package/dist/cli/config.d.ts +17 -0
  35. package/dist/cli/config.d.ts.map +1 -0
  36. package/dist/cli/config.js +94 -0
  37. package/dist/cli/config.js.map +1 -0
  38. package/dist/cli/index.d.ts +3 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +371 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/cli/proxy.d.ts +2 -0
  43. package/dist/cli/proxy.d.ts.map +1 -0
  44. package/dist/cli/proxy.js +171 -0
  45. package/dist/cli/proxy.js.map +1 -0
  46. package/dist/data/catalog.d.ts +54 -0
  47. package/dist/data/catalog.d.ts.map +1 -0
  48. package/dist/data/catalog.js +108 -0
  49. package/dist/data/catalog.js.map +1 -0
  50. package/dist/db/dal.d.ts +75 -0
  51. package/dist/db/dal.d.ts.map +1 -0
  52. package/dist/db/dal.js +124 -0
  53. package/dist/db/dal.js.map +1 -0
  54. package/dist/index.js +156 -0
  55. package/dist/index.ts +134 -0
  56. package/dist/logger.d.ts +8 -0
  57. package/dist/logger.d.ts.map +1 -0
  58. package/dist/logger.js +19 -0
  59. package/dist/logger.js.map +1 -0
  60. package/dist/test/setup.d.ts +2 -0
  61. package/dist/test/setup.d.ts.map +1 -0
  62. package/dist/test/setup.js +27 -0
  63. package/dist/test/setup.js.map +1 -0
  64. package/package.json +82 -0
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * ZeroAuth Curated Catalog Data Loader
4
+ *
5
+ * Loads the curated-catalog.json file generated by the Python generator script.
6
+ * Provides static data for intent-based routing without database dependencies.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.catalogLoader = void 0;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ class CatalogLoader {
46
+ constructor() {
47
+ this.catalog = null;
48
+ // Path relative to the API startup location
49
+ this.catalogPath = path.join(__dirname, "../../data/curated-catalog.json");
50
+ }
51
+ /**
52
+ * Load the curated catalog from JSON file.
53
+ * Should be called at API startup.
54
+ */
55
+ loadCatalog() {
56
+ try {
57
+ if (!fs.existsSync(this.catalogPath)) {
58
+ throw new Error(`Curated catalog file not found: ${this.catalogPath}`);
59
+ }
60
+ const data = fs.readFileSync(this.catalogPath, "utf-8");
61
+ this.catalog = JSON.parse(data);
62
+ console.log(`📊 Loaded curated catalog with ${this.catalog.length} models`);
63
+ return this.catalog;
64
+ }
65
+ catch (error) {
66
+ console.error("❌ Failed to load curated catalog:", error);
67
+ throw error;
68
+ }
69
+ }
70
+ /**
71
+ * Get the loaded catalog. Throws if not loaded.
72
+ */
73
+ getCatalog() {
74
+ if (!this.catalog) {
75
+ throw new Error("Catalog not loaded. Call loadCatalog() first.");
76
+ }
77
+ return this.catalog;
78
+ }
79
+ /**
80
+ * Find a model by intent alias (e.g., "intent:budget" -> "zeroauth-budget")
81
+ * This now filters for enabled models only.
82
+ */
83
+ findModelByIntent(intentAlias) {
84
+ const catalog = this.getCatalog();
85
+ // Prioritize enabled models for the given intent
86
+ return catalog.find((model) => model.intent_alias === intentAlias && model.enabled) || null;
87
+ }
88
+ /**
89
+ * Get all available intent aliases for error messages
90
+ */
91
+ getAvailableIntents() {
92
+ const catalog = this.getCatalog();
93
+ return [...new Set(catalog.map((model) => model.intent_alias))];
94
+ }
95
+ /**
96
+ * Get the default Free Developer Profile (no compliance checks)
97
+ */
98
+ getDefaultProfile() {
99
+ return {
100
+ tier: "Tier 1: Developer (Free)",
101
+ required_tags: {}, // Empty - no compliance enforcement
102
+ optimization_goal: "COST",
103
+ };
104
+ }
105
+ }
106
+ // Singleton instance
107
+ exports.catalogLoader = new CatalogLoader();
108
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/data/catalog.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAsB7B,MAAM,aAAa;IAIjB;QAHQ,YAAO,GAA0B,IAAI,CAAC;QAI5C,4CAA4C;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iCAAiC,CAAC,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACH,WAAW;QACT,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;YAElD,OAAO,CAAC,GAAG,CACT,kCAAkC,IAAI,CAAC,OAAO,CAAC,MAAM,SAAS,CAC/D,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YAC1D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAC,WAAmB;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,iDAAiD;QACjD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IAC9F,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,OAAO;YACL,IAAI,EAAE,0BAA0B;YAChC,aAAa,EAAE,EAAE,EAAE,oCAAoC;YACvD,iBAAiB,EAAE,MAAM;SAC1B,CAAC;IACJ,CAAC;CACF;AAED,qBAAqB;AACR,QAAA,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { PrismaClient, Prisma } from "@prisma/client";
2
+ declare const prisma: PrismaClient<Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
3
+ /**
4
+ * Finds an existing UserIdentity by their Clerk ID, or creates a new
5
+ * Organization, SecurityProfile, and UserIdentity in a single transaction
6
+ * if it's their first time logging in.
7
+ *
8
+ * @param clerkUserId - The 'id' of the user from the Clerk JWT (e.g., 'user_clerk_jane').
9
+ * @returns The UserIdentity and its associated SecurityProfile.
10
+ */
11
+ export declare function findOrCreateUserIdentity(clerkUserId: string): Promise<{
12
+ securityProfile: {
13
+ organization: {
14
+ name: string;
15
+ id: string;
16
+ plan_tier: string;
17
+ stripe_customer_id: string | null;
18
+ createdAt: Date;
19
+ updatedAt: Date;
20
+ };
21
+ complianceFrameworks: {
22
+ security_profile_id: string;
23
+ framework_id: string;
24
+ }[];
25
+ } & {
26
+ name: string;
27
+ id: string;
28
+ createdAt: Date;
29
+ updatedAt: Date;
30
+ organization_id: string;
31
+ };
32
+ } & {
33
+ id: string;
34
+ createdAt: Date;
35
+ security_profile_id: string;
36
+ }>;
37
+ /**
38
+ * Finds an existing WorkloadIdentity by its cloud-native identifier,
39
+ * or returns null if not found.
40
+ *
41
+ * @param cloud - The cloud provider (e.g., "AWS", "GCP").
42
+ * @param cloudIdentity - The unique cloud identifier (e.g., an ARN).
43
+ * @returns The WorkloadIdentity and its SecurityProfile, or null.
44
+ */
45
+ export declare function findWorkloadIdentity(cloud: string, cloudIdentity: string): Promise<({
46
+ securityProfile: {
47
+ organization: {
48
+ name: string;
49
+ id: string;
50
+ plan_tier: string;
51
+ stripe_customer_id: string | null;
52
+ createdAt: Date;
53
+ updatedAt: Date;
54
+ };
55
+ complianceFrameworks: {
56
+ security_profile_id: string;
57
+ framework_id: string;
58
+ }[];
59
+ } & {
60
+ name: string;
61
+ id: string;
62
+ createdAt: Date;
63
+ updatedAt: Date;
64
+ organization_id: string;
65
+ };
66
+ } & {
67
+ id: string;
68
+ createdAt: Date;
69
+ security_profile_id: string;
70
+ cloud: string;
71
+ cloud_identity: string;
72
+ }) | null>;
73
+ export declare function createWorkloadIdentity(organizationId: string, profileName: string, cloud: string, cloudIdentity: string, complianceFrameworks?: string[]): Promise<void>;
74
+ export { prisma };
75
+ //# sourceMappingURL=dal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dal.d.ts","sourceRoot":"","sources":["../../src/db/dal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAItD,QAAA,MAAM,MAAM,uGAAqB,CAAC;AAElC;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;GAkFjE;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;WAkCtB;AAED,wBAAsB,sBAAsB,CAC1C,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,oBAAoB,GAAE,MAAM,EAAO,iBASpC;AAID,OAAO,EAAE,MAAM,EAAE,CAAC"}
package/dist/db/dal.js ADDED
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prisma = void 0;
4
+ exports.findOrCreateUserIdentity = findOrCreateUserIdentity;
5
+ exports.findWorkloadIdentity = findWorkloadIdentity;
6
+ exports.createWorkloadIdentity = createWorkloadIdentity;
7
+ const client_1 = require("@prisma/client");
8
+ const logger_1 = require("../logger");
9
+ // Initialize a singleton Prisma Client
10
+ const prisma = new client_1.PrismaClient();
11
+ exports.prisma = prisma;
12
+ /**
13
+ * Finds an existing UserIdentity by their Clerk ID, or creates a new
14
+ * Organization, SecurityProfile, and UserIdentity in a single transaction
15
+ * if it's their first time logging in.
16
+ *
17
+ * @param clerkUserId - The 'id' of the user from the Clerk JWT (e.g., 'user_clerk_jane').
18
+ * @returns The UserIdentity and its associated SecurityProfile.
19
+ */
20
+ async function findOrCreateUserIdentity(clerkUserId) {
21
+ logger_1.log.info({ clerkUserId }, "Finding or creating user identity...");
22
+ // 1. Check if user identity already exists
23
+ const existingIdentity = await prisma.userIdentity.findUnique({
24
+ where: { id: clerkUserId },
25
+ include: {
26
+ securityProfile: {
27
+ include: {
28
+ organization: true,
29
+ complianceFrameworks: true,
30
+ },
31
+ },
32
+ },
33
+ });
34
+ if (existingIdentity) {
35
+ logger_1.log.info({ clerkUserId, profileId: existingIdentity.security_profile_id }, "Found existing user identity.");
36
+ return existingIdentity;
37
+ }
38
+ // 2. User does not exist. Create new org, profile, and identity
39
+ // in a single transaction [cite: 297-300].
40
+ logger_1.log.info({ clerkUserId }, "No existing identity found. Creating new user...");
41
+ try {
42
+ const newUserIdentity = await prisma.$transaction(async (tx) => {
43
+ // Create the Organization [cite: 298]
44
+ const newOrg = await tx.organization.create({
45
+ data: {
46
+ name: `${clerkUserId}'s Organization`,
47
+ plan_tier: "free",
48
+ },
49
+ });
50
+ // Create the default SecurityProfile [cite: 299]
51
+ const newProfile = await tx.securityProfile.create({
52
+ data: {
53
+ name: "Default Profile",
54
+ organization_id: newOrg.id,
55
+ },
56
+ });
57
+ // Create the UserIdentity and link it all [cite: 300]
58
+ const newUser = await tx.userIdentity.create({
59
+ data: {
60
+ id: clerkUserId,
61
+ security_profile_id: newProfile.id,
62
+ },
63
+ include: {
64
+ securityProfile: {
65
+ include: {
66
+ organization: true,
67
+ complianceFrameworks: true,
68
+ },
69
+ },
70
+ },
71
+ });
72
+ return newUser;
73
+ });
74
+ logger_1.log.info({
75
+ clerkUserId,
76
+ profileId: newUserIdentity.security_profile_id,
77
+ orgId: newUserIdentity.securityProfile.organization_id,
78
+ }, "Successfully created new user, org, and default profile.");
79
+ return newUserIdentity;
80
+ }
81
+ catch (error) {
82
+ logger_1.log.error({ clerkUserId, error }, "Error during new user auto-provisioning transaction.");
83
+ throw new Error("Failed to provision new user identity.");
84
+ }
85
+ }
86
+ /**
87
+ * Finds an existing WorkloadIdentity by its cloud-native identifier,
88
+ * or returns null if not found.
89
+ *
90
+ * @param cloud - The cloud provider (e.g., "AWS", "GCP").
91
+ * @param cloudIdentity - The unique cloud identifier (e.g., an ARN).
92
+ * @returns The WorkloadIdentity and its SecurityProfile, or null.
93
+ */
94
+ async function findWorkloadIdentity(cloud, cloudIdentity) {
95
+ logger_1.log.info({ cloud, cloudIdentity }, "Finding workload identity...");
96
+ const workloadIdentity = await prisma.workloadIdentity.findUnique({
97
+ where: {
98
+ cloud_cloud_identity: {
99
+ cloud: cloud,
100
+ cloud_identity: cloudIdentity,
101
+ },
102
+ },
103
+ include: {
104
+ securityProfile: {
105
+ include: {
106
+ organization: true,
107
+ complianceFrameworks: true,
108
+ },
109
+ },
110
+ },
111
+ });
112
+ if (workloadIdentity) {
113
+ logger_1.log.info({ cloud, cloudIdentity, profileId: workloadIdentity.security_profile_id }, "Found existing workload identity.");
114
+ return workloadIdentity;
115
+ }
116
+ logger_1.log.warn({ cloud, cloudIdentity }, "Workload identity not found in database.");
117
+ return null;
118
+ }
119
+ async function createWorkloadIdentity(organizationId, profileName, cloud, cloudIdentity, complianceFrameworks = []) {
120
+ logger_1.log.info({ organizationId, profileName, cloud, cloudIdentity }, "Creating new workload identity...");
121
+ // This will be implemented with proper database connection once API is fully connected
122
+ throw new Error("Database operations not supported in this environment");
123
+ }
124
+ //# sourceMappingURL=dal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dal.js","sourceRoot":"","sources":["../../src/db/dal.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.handler = handler;
40
+ const axios_1 = __importDefault(require("axios"));
41
+ const jwt = __importStar(require("jsonwebtoken"));
42
+ const jwk_to_pem_1 = __importDefault(require("jwk-to-pem"));
43
+ // --- Identity Provider Agnostic Configuration ---
44
+ const OIDC_ISSUER_URL = process.env.OIDC_ISSUER_URL;
45
+ const OIDC_JWKS_URL = process.env.OIDC_JWKS_URL; // New variable for internal JWKS fetching
46
+ const OIDC_AUDIENCE = process.env.OIDC_AUDIENCE;
47
+ // JWKS cache
48
+ let jwksCache = null;
49
+ let jwksCacheTime = 0;
50
+ const JWKS_CACHE_DURATION = 3600000; // 1 hour
51
+ async function getJwks() {
52
+ if (!OIDC_JWKS_URL) {
53
+ throw new Error("OIDC_JWKS_URL environment variable is not set.");
54
+ }
55
+ const now = Date.now();
56
+ if (jwksCache && now - jwksCacheTime < JWKS_CACHE_DURATION) {
57
+ return jwksCache;
58
+ }
59
+ // Use OIDC_JWKS_URL directly if it's a full URL, otherwise construct from OIDC_ISSUER_URL
60
+ const jwksUrl = OIDC_JWKS_URL && OIDC_JWKS_URL.includes("://")
61
+ ? OIDC_JWKS_URL
62
+ : `${OIDC_ISSUER_URL}/.well-known/jwks.json`;
63
+ try {
64
+ const response = await axios_1.default.get(jwksUrl);
65
+ jwksCache = response.data;
66
+ jwksCacheTime = now;
67
+ return jwksCache;
68
+ }
69
+ catch (error) {
70
+ console.error("Error fetching JWKS:", error);
71
+ throw new Error(`Could not fetch JWKS`);
72
+ }
73
+ }
74
+ async function verifyToken(token) {
75
+ const jwks = await getJwks();
76
+ const unverifiedHeader = jwt.decode(token, { complete: true });
77
+ if (!unverifiedHeader ||
78
+ typeof unverifiedHeader === "string" ||
79
+ !unverifiedHeader.header.kid) {
80
+ throw new Error("Invalid token header.");
81
+ }
82
+ const key = jwks.keys.find((k) => k.kid === unverifiedHeader.header.kid);
83
+ if (!key) {
84
+ throw new Error("Could not find a matching public key.");
85
+ }
86
+ const pem = (0, jwk_to_pem_1.default)(key);
87
+ try {
88
+ const payload = jwt.verify(token, pem, {
89
+ algorithms: ["RS256"],
90
+ audience: OIDC_AUDIENCE,
91
+ issuer: OIDC_ISSUER_URL,
92
+ });
93
+ return payload;
94
+ }
95
+ catch (error) {
96
+ throw new Error(`Token is invalid: ${error}`);
97
+ }
98
+ }
99
+ async function handler(event) {
100
+ console.log("=== Authorizer handler called ===");
101
+ console.log("Event:", JSON.stringify(event, null, 2));
102
+ try {
103
+ const authHeader = event.headers?.authorization || event.headers?.Authorization;
104
+ console.log("Auth header present:", !!authHeader);
105
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
106
+ console.log("Invalid or missing auth header");
107
+ return {
108
+ principalId: "unauthorized",
109
+ policyDocument: {
110
+ Version: "2012-10-17",
111
+ Statement: [
112
+ {
113
+ Action: "execute-api:Invoke",
114
+ Effect: "Deny",
115
+ Resource: event.methodArn,
116
+ },
117
+ ],
118
+ },
119
+ };
120
+ }
121
+ const token = authHeader.substring(7);
122
+ console.log("Token extracted, verifying...");
123
+ await verifyToken(token);
124
+ console.log("Token verified successfully");
125
+ return {
126
+ principalId: "user",
127
+ policyDocument: {
128
+ Version: "2012-10-17",
129
+ Statement: [
130
+ {
131
+ Action: "execute-api:Invoke",
132
+ Effect: "Allow",
133
+ Resource: event.methodArn,
134
+ },
135
+ ],
136
+ },
137
+ };
138
+ }
139
+ catch (error) {
140
+ console.error("=== Authorization failed ===");
141
+ console.error("Error:", error);
142
+ return {
143
+ principalId: "unauthorized",
144
+ policyDocument: {
145
+ Version: "2012-10-17",
146
+ Statement: [
147
+ {
148
+ Action: "execute-api:Invoke",
149
+ Effect: "Deny",
150
+ Resource: event.methodArn,
151
+ },
152
+ ],
153
+ },
154
+ };
155
+ }
156
+ }
package/dist/index.ts ADDED
@@ -0,0 +1,134 @@
1
+ import axios from "axios";
2
+ import * as jwt from "jsonwebtoken";
3
+ import jwkToPem from "jwk-to-pem";
4
+
5
+ // --- Identity Provider Agnostic Configuration ---
6
+ const OIDC_ISSUER_URL = process.env.OIDC_ISSUER_URL;
7
+ const OIDC_JWKS_URL = process.env.OIDC_JWKS_URL; // New variable for internal JWKS fetching
8
+ const OIDC_AUDIENCE = process.env.OIDC_AUDIENCE;
9
+
10
+ // JWKS cache
11
+ let jwksCache: any = null;
12
+ let jwksCacheTime = 0;
13
+ const JWKS_CACHE_DURATION = 3600000; // 1 hour
14
+
15
+ async function getJwks() {
16
+ if (!OIDC_JWKS_URL) {
17
+ throw new Error("OIDC_JWKS_URL environment variable is not set.");
18
+ }
19
+
20
+ const now = Date.now();
21
+ if (jwksCache && now - jwksCacheTime < JWKS_CACHE_DURATION) {
22
+ return jwksCache;
23
+ }
24
+
25
+ // Use OIDC_JWKS_URL directly if it's a full URL, otherwise construct from OIDC_ISSUER_URL
26
+ const jwksUrl =
27
+ OIDC_JWKS_URL && OIDC_JWKS_URL.includes("://")
28
+ ? OIDC_JWKS_URL
29
+ : `${OIDC_ISSUER_URL}/.well-known/jwks.json`;
30
+ try {
31
+ const response = await axios.get(jwksUrl);
32
+ jwksCache = response.data;
33
+ jwksCacheTime = now;
34
+ return jwksCache;
35
+ } catch (error) {
36
+ console.error("Error fetching JWKS:", error);
37
+ throw new Error(`Could not fetch JWKS`);
38
+ }
39
+ }
40
+
41
+ async function verifyToken(token: string) {
42
+ const jwks = await getJwks();
43
+ const unverifiedHeader = jwt.decode(token, { complete: true });
44
+
45
+ if (
46
+ !unverifiedHeader ||
47
+ typeof unverifiedHeader === "string" ||
48
+ !unverifiedHeader.header.kid
49
+ ) {
50
+ throw new Error("Invalid token header.");
51
+ }
52
+
53
+ const key = jwks.keys.find((k: any) => k.kid === unverifiedHeader.header.kid);
54
+ if (!key) {
55
+ throw new Error("Could not find a matching public key.");
56
+ }
57
+
58
+ const pem = jwkToPem(key as jwkToPem.JWK);
59
+
60
+ try {
61
+ const payload = jwt.verify(token, pem, {
62
+ algorithms: ["RS256"],
63
+ audience: OIDC_AUDIENCE,
64
+ issuer: OIDC_ISSUER_URL,
65
+ });
66
+ return payload;
67
+ } catch (error) {
68
+ throw new Error(`Token is invalid: ${error}`);
69
+ }
70
+ }
71
+
72
+ export async function handler(event: any) {
73
+ console.log("=== Authorizer handler called ===");
74
+ console.log("Event:", JSON.stringify(event, null, 2));
75
+
76
+ try {
77
+ const authHeader =
78
+ event.headers?.authorization || event.headers?.Authorization;
79
+ console.log("Auth header present:", !!authHeader);
80
+
81
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
82
+ console.log("Invalid or missing auth header");
83
+ return {
84
+ principalId: "unauthorized",
85
+ policyDocument: {
86
+ Version: "2012-10-17",
87
+ Statement: [
88
+ {
89
+ Action: "execute-api:Invoke",
90
+ Effect: "Deny",
91
+ Resource: event.methodArn,
92
+ },
93
+ ],
94
+ },
95
+ };
96
+ }
97
+
98
+ const token = authHeader.substring(7);
99
+ console.log("Token extracted, verifying...");
100
+
101
+ await verifyToken(token);
102
+ console.log("Token verified successfully");
103
+
104
+ return {
105
+ principalId: "user",
106
+ policyDocument: {
107
+ Version: "2012-10-17",
108
+ Statement: [
109
+ {
110
+ Action: "execute-api:Invoke",
111
+ Effect: "Allow",
112
+ Resource: event.methodArn,
113
+ },
114
+ ],
115
+ },
116
+ };
117
+ } catch (error) {
118
+ console.error("=== Authorization failed ===");
119
+ console.error("Error:", error);
120
+ return {
121
+ principalId: "unauthorized",
122
+ policyDocument: {
123
+ Version: "2012-10-17",
124
+ Statement: [
125
+ {
126
+ Action: "execute-api:Invoke",
127
+ Effect: "Deny",
128
+ Resource: event.methodArn,
129
+ },
130
+ ],
131
+ },
132
+ };
133
+ }
134
+ }
@@ -0,0 +1,8 @@
1
+ export declare const log: import("pino").Logger<{
2
+ level: string;
3
+ serializers: {
4
+ err: typeof import("pino-std-serializers").err;
5
+ error: typeof import("pino-std-serializers").err;
6
+ };
7
+ }>;
8
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,GAAG;;;;;;EAAS,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.log = void 0;
7
+ // src/logger.ts - Centralized logging system
8
+ const pino_1 = __importDefault(require("pino"));
9
+ // Create logger configuration
10
+ const logger = (0, pino_1.default)({
11
+ level: process.env.ZEROAUTH_DEBUG ? "debug" : "info",
12
+ serializers: {
13
+ err: pino_1.default.stdSerializers.err,
14
+ error: pino_1.default.stdSerializers.err,
15
+ },
16
+ }, process.stdout);
17
+ // Export the logger directly
18
+ exports.log = logger;
19
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;;;;AAAA,6CAA6C;AAC7C,gDAAwB;AAExB,8BAA8B;AAC9B,MAAM,MAAM,GAAG,IAAA,cAAI,EACjB;IACE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;IACpD,WAAW,EAAE;QACX,GAAG,EAAE,cAAI,CAAC,cAAc,CAAC,GAAG;QAC5B,KAAK,EAAE,cAAI,CAAC,cAAc,CAAC,GAAG;KAC/B;CACF,EACD,OAAO,CAAC,MAAM,CACf,CAAC;AAEF,6BAA6B;AAChB,QAAA,GAAG,GAAG,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":""}