@centrali-io/centrali-sdk 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +107 -0
  2. package/index.ts +201 -0
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1582,6 +1582,84 @@ class CentraliSDK {
1582
1582
  return this.request('GET', path, null, queryParams);
1583
1583
  });
1584
1584
  }
1585
+ // ------------------ Authorization API Methods (BYOT) ------------------
1586
+ /**
1587
+ * Check if an action is authorized for an external token.
1588
+ *
1589
+ * Use this method when you want to authorize access using tokens from your
1590
+ * own identity provider (Clerk, Auth0, Okta, etc.) instead of Centrali's
1591
+ * built-in authentication.
1592
+ *
1593
+ * **Use Cases:**
1594
+ * 1. **AuthZ-as-a-Service**: Define custom resources (orders, invoices) in Centrali
1595
+ * and use it purely for authorization decisions.
1596
+ * 2. **External IdP for Centrali resources**: Access Centrali data (records, files)
1597
+ * using your corporate IdP tokens.
1598
+ *
1599
+ * **Prerequisites:**
1600
+ * - Configure an External Auth Provider in Centrali Console (Settings → External Auth)
1601
+ * - Define claim mappings to extract attributes from your JWT
1602
+ * - Create policies that reference the extracted attributes (prefixed with `ext_`)
1603
+ *
1604
+ * @example
1605
+ * // Simple authorization check
1606
+ * const result = await client.checkAuthorization({
1607
+ * token: clerkJWT,
1608
+ * resource: 'orders',
1609
+ * action: 'read'
1610
+ * });
1611
+ *
1612
+ * if (result.data.allowed) {
1613
+ * // Proceed with the action
1614
+ * }
1615
+ *
1616
+ * @example
1617
+ * // Authorization with context for policy evaluation
1618
+ * const result = await client.checkAuthorization({
1619
+ * token: clerkJWT,
1620
+ * resource: 'orders',
1621
+ * action: 'approve',
1622
+ * context: {
1623
+ * orderId: 'order-123',
1624
+ * orderAmount: 50000,
1625
+ * department: 'sales'
1626
+ * }
1627
+ * });
1628
+ *
1629
+ * // Policy can check: ext_role == 'manager' AND request_metadata.orderAmount > 10000
1630
+ *
1631
+ * @param options - Authorization check options
1632
+ * @returns Promise resolving to the authorization result
1633
+ */
1634
+ checkAuthorization(options) {
1635
+ return __awaiter(this, void 0, void 0, function* () {
1636
+ const { token, resource, action, resourceCategory = 'custom', context } = options;
1637
+ const path = `/workspace/${this.options.workspaceId}/api/v1/access/evaluate`;
1638
+ const body = {
1639
+ action,
1640
+ resource_name: resource,
1641
+ resource_category: resourceCategory,
1642
+ request_data: context ? { request_metadata: context } : undefined
1643
+ };
1644
+ // Make request with the external token
1645
+ const response = yield this.axios.request({
1646
+ method: 'POST',
1647
+ url: path,
1648
+ data: body,
1649
+ headers: {
1650
+ 'Authorization': `Bearer ${token}`,
1651
+ 'Content-Type': 'application/json'
1652
+ }
1653
+ });
1654
+ return {
1655
+ data: {
1656
+ allowed: response.data.response === 'allow',
1657
+ decision: response.data.response,
1658
+ message: response.data.message
1659
+ }
1660
+ };
1661
+ });
1662
+ }
1585
1663
  }
1586
1664
  exports.CentraliSDK = CentraliSDK;
1587
1665
  /**
@@ -1675,5 +1753,34 @@ exports.CentraliSDK = CentraliSDK;
1675
1753
  * structures: ['users', 'orders'],
1676
1754
  * limit: 50
1677
1755
  * });
1756
+ *
1757
+ * // ---- Authorization (BYOT - Bring Your Own Token) ----
1758
+ *
1759
+ * // Simple authorization check with external IdP token:
1760
+ * const authResult = await client.checkAuthorization({
1761
+ * token: clerkJWT, // Token from Clerk, Auth0, Okta, etc.
1762
+ * resource: 'orders',
1763
+ * action: 'read'
1764
+ * });
1765
+ *
1766
+ * if (authResult.data.allowed) {
1767
+ * console.log('Access granted');
1768
+ * } else {
1769
+ * console.log('Access denied:', authResult.data.message);
1770
+ * }
1771
+ *
1772
+ * // Authorization with context for policy evaluation:
1773
+ * const approveResult = await client.checkAuthorization({
1774
+ * token: clerkJWT,
1775
+ * resource: 'orders',
1776
+ * action: 'approve',
1777
+ * context: {
1778
+ * orderId: 'order-123',
1779
+ * orderAmount: 50000,
1780
+ * department: 'sales'
1781
+ * }
1782
+ * });
1783
+ * // Policy can reference: ext_role, ext_department (from JWT claims)
1784
+ * // and request_metadata.orderId, request_metadata.orderAmount (from context)
1678
1785
  *```
1679
1786
  */
package/index.ts CHANGED
@@ -412,6 +412,90 @@ export interface ApiResponse<T> {
412
412
  updatedAt?: string;
413
413
  }
414
414
 
415
+ // =====================================================
416
+ // Authorization Types (BYOT - Bring Your Own Token)
417
+ // =====================================================
418
+
419
+ /**
420
+ * Resource category for authorization.
421
+ * - 'workspace': Workspace-level resources (e.g., settings, members)
422
+ * - 'structure': Structure-level resources (e.g., specific records)
423
+ * - 'custom': Custom resources defined by the user for AuthZ-as-a-Service
424
+ */
425
+ export type ResourceCategory = 'workspace' | 'structure' | 'custom';
426
+
427
+ /**
428
+ * Options for authorization check.
429
+ * Use this when authorizing access using an external IdP token (BYOT).
430
+ */
431
+ export interface CheckAuthorizationOptions {
432
+ /**
433
+ * The JWT token from your external identity provider (e.g., Clerk, Auth0, Okta).
434
+ * The token will be validated against the configured external auth provider.
435
+ */
436
+ token: string;
437
+
438
+ /**
439
+ * The resource being accessed.
440
+ * Can be a Centrali system resource (e.g., 'records', 'files') or a custom
441
+ * resource you've defined for AuthZ-as-a-Service (e.g., 'orders', 'invoices').
442
+ */
443
+ resource: string;
444
+
445
+ /**
446
+ * The action being performed on the resource.
447
+ * Common actions: 'create', 'read', 'update', 'delete', 'admin'
448
+ * You can also define custom actions (e.g., 'approve', 'publish').
449
+ */
450
+ action: string;
451
+
452
+ /**
453
+ * Resource category for authorization evaluation.
454
+ * - 'workspace': Workspace-level resources
455
+ * - 'structure': Structure-level resources
456
+ * - 'custom': Custom resources for AuthZ-as-a-Service
457
+ * @default 'custom'
458
+ */
459
+ resourceCategory?: ResourceCategory;
460
+
461
+ /**
462
+ * Optional context data for policy evaluation.
463
+ * This data becomes available as `request_metadata` in policies.
464
+ *
465
+ * @example
466
+ * // Policy can reference: request_metadata.orderId, request_metadata.amount
467
+ * context: {
468
+ * orderId: 'order-123',
469
+ * amount: 50000,
470
+ * department: 'sales'
471
+ * }
472
+ */
473
+ context?: Record<string, unknown>;
474
+ }
475
+
476
+ /**
477
+ * Result of an authorization check.
478
+ */
479
+ export interface AuthorizationResult {
480
+ /**
481
+ * Whether the action is allowed.
482
+ */
483
+ allowed: boolean;
484
+
485
+ /**
486
+ * The decision from the policy evaluator.
487
+ * - 'allow': Access granted
488
+ * - 'deny': Access denied
489
+ * - 'not_applicable': No matching policy found
490
+ */
491
+ decision: 'allow' | 'deny' | 'not_applicable';
492
+
493
+ /**
494
+ * Human-readable message explaining the decision.
495
+ */
496
+ message?: string;
497
+ }
498
+
415
499
  // =====================================================
416
500
  // Trigger Types
417
501
  // =====================================================
@@ -2713,6 +2797,94 @@ export class CentraliSDK {
2713
2797
  return this.request<SearchResponse>('GET', path, null, queryParams);
2714
2798
  }
2715
2799
 
2800
+ // ------------------ Authorization API Methods (BYOT) ------------------
2801
+
2802
+ /**
2803
+ * Check if an action is authorized for an external token.
2804
+ *
2805
+ * Use this method when you want to authorize access using tokens from your
2806
+ * own identity provider (Clerk, Auth0, Okta, etc.) instead of Centrali's
2807
+ * built-in authentication.
2808
+ *
2809
+ * **Use Cases:**
2810
+ * 1. **AuthZ-as-a-Service**: Define custom resources (orders, invoices) in Centrali
2811
+ * and use it purely for authorization decisions.
2812
+ * 2. **External IdP for Centrali resources**: Access Centrali data (records, files)
2813
+ * using your corporate IdP tokens.
2814
+ *
2815
+ * **Prerequisites:**
2816
+ * - Configure an External Auth Provider in Centrali Console (Settings → External Auth)
2817
+ * - Define claim mappings to extract attributes from your JWT
2818
+ * - Create policies that reference the extracted attributes (prefixed with `ext_`)
2819
+ *
2820
+ * @example
2821
+ * // Simple authorization check
2822
+ * const result = await client.checkAuthorization({
2823
+ * token: clerkJWT,
2824
+ * resource: 'orders',
2825
+ * action: 'read'
2826
+ * });
2827
+ *
2828
+ * if (result.data.allowed) {
2829
+ * // Proceed with the action
2830
+ * }
2831
+ *
2832
+ * @example
2833
+ * // Authorization with context for policy evaluation
2834
+ * const result = await client.checkAuthorization({
2835
+ * token: clerkJWT,
2836
+ * resource: 'orders',
2837
+ * action: 'approve',
2838
+ * context: {
2839
+ * orderId: 'order-123',
2840
+ * orderAmount: 50000,
2841
+ * department: 'sales'
2842
+ * }
2843
+ * });
2844
+ *
2845
+ * // Policy can check: ext_role == 'manager' AND request_metadata.orderAmount > 10000
2846
+ *
2847
+ * @param options - Authorization check options
2848
+ * @returns Promise resolving to the authorization result
2849
+ */
2850
+ public async checkAuthorization(
2851
+ options: CheckAuthorizationOptions
2852
+ ): Promise<ApiResponse<AuthorizationResult>> {
2853
+ const { token, resource, action, resourceCategory = 'custom', context } = options;
2854
+
2855
+ const path = `/workspace/${this.options.workspaceId}/api/v1/access/evaluate`;
2856
+
2857
+ const body = {
2858
+ action,
2859
+ resource_name: resource,
2860
+ resource_category: resourceCategory,
2861
+ request_data: context ? { request_metadata: context } : undefined
2862
+ };
2863
+
2864
+ // Make request with the external token
2865
+ const response = await this.axios.request<{
2866
+ status: string;
2867
+ response: 'allow' | 'deny' | 'not_applicable';
2868
+ message?: string;
2869
+ }>({
2870
+ method: 'POST',
2871
+ url: path,
2872
+ data: body,
2873
+ headers: {
2874
+ 'Authorization': `Bearer ${token}`,
2875
+ 'Content-Type': 'application/json'
2876
+ }
2877
+ });
2878
+
2879
+ return {
2880
+ data: {
2881
+ allowed: response.data.response === 'allow',
2882
+ decision: response.data.response,
2883
+ message: response.data.message
2884
+ }
2885
+ };
2886
+ }
2887
+
2716
2888
  }
2717
2889
 
2718
2890
  /**
@@ -2806,5 +2978,34 @@ export class CentraliSDK {
2806
2978
  * structures: ['users', 'orders'],
2807
2979
  * limit: 50
2808
2980
  * });
2981
+ *
2982
+ * // ---- Authorization (BYOT - Bring Your Own Token) ----
2983
+ *
2984
+ * // Simple authorization check with external IdP token:
2985
+ * const authResult = await client.checkAuthorization({
2986
+ * token: clerkJWT, // Token from Clerk, Auth0, Okta, etc.
2987
+ * resource: 'orders',
2988
+ * action: 'read'
2989
+ * });
2990
+ *
2991
+ * if (authResult.data.allowed) {
2992
+ * console.log('Access granted');
2993
+ * } else {
2994
+ * console.log('Access denied:', authResult.data.message);
2995
+ * }
2996
+ *
2997
+ * // Authorization with context for policy evaluation:
2998
+ * const approveResult = await client.checkAuthorization({
2999
+ * token: clerkJWT,
3000
+ * resource: 'orders',
3001
+ * action: 'approve',
3002
+ * context: {
3003
+ * orderId: 'order-123',
3004
+ * orderAmount: 50000,
3005
+ * department: 'sales'
3006
+ * }
3007
+ * });
3008
+ * // Policy can reference: ext_role, ext_department (from JWT claims)
3009
+ * // and request_metadata.orderId, request_metadata.orderAmount (from context)
2809
3010
  *```
2810
3011
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centrali-io/centrali-sdk",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Centrali Node SDK",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",