@objectstack/core 14.8.0 → 15.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.
- package/dist/index.cjs +70 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -1
- package/dist/index.d.ts +117 -1
- package/dist/index.js +67 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -8,6 +8,7 @@ import { ConflictResolutionStrategy, ApiRegistryEntryInput, ApiRegistryEntry, Ap
|
|
|
8
8
|
import * as QA from '@objectstack/spec/qa';
|
|
9
9
|
import { KeyObject } from 'node:crypto';
|
|
10
10
|
import { PluginCapability, PluginPermissions as PluginPermissions$1, PluginPermissionSet, ResourceType, PermissionAction, PluginPermission, SandboxConfig, KernelSecurityScanResult, KernelSecurityVulnerability, PluginHealthCheck, PluginHealthStatus as PluginHealthStatus$1, PluginHealthReport, HotReloadConfig, VersionConstraint, DependencyConflict, SemanticVersion, CompatibilityLevel } from '@objectstack/spec/kernel';
|
|
11
|
+
import { AuthzPosture } from '@objectstack/spec/security';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Service Lifecycle Types
|
|
@@ -1739,6 +1740,16 @@ interface ResolvedAuthzContext {
|
|
|
1739
1740
|
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1740
1741
|
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1741
1742
|
org_user_ids: string[];
|
|
1743
|
+
/**
|
|
1744
|
+
* [ADR-0095 D2/D3] The monotonic posture rung this principal resolves to,
|
|
1745
|
+
* DERIVED once here from held capability grants (never a better-auth role):
|
|
1746
|
+
* `PLATFORM_ADMIN` (unscoped `admin_full_access`) > `TENANT_ADMIN`
|
|
1747
|
+
* (`organization_admin`) > `MEMBER` (the authenticated floor). `EXTERNAL` is
|
|
1748
|
+
* defined/test-locked but never resolved yet (no external principal type —
|
|
1749
|
+
* see `posture-ladder.ts`). Present only for an authenticated principal;
|
|
1750
|
+
* anonymous requests carry no rung.
|
|
1751
|
+
*/
|
|
1752
|
+
posture?: AuthzPosture;
|
|
1742
1753
|
}
|
|
1743
1754
|
interface ResolveAuthzInput {
|
|
1744
1755
|
/** Data engine (ObjectQL) exposing `find(object, { where, limit, context })`. */
|
|
@@ -1778,6 +1789,111 @@ declare function resolveLocalizationContext(input: ResolveLocalizationInput): Pr
|
|
|
1778
1789
|
currency?: string;
|
|
1779
1790
|
}>;
|
|
1780
1791
|
|
|
1792
|
+
/**
|
|
1793
|
+
* ── The monotonic posture ladder (ADR-0095 D2/D3) ───────────────────────────
|
|
1794
|
+
*
|
|
1795
|
+
* The principal-tiering enum resolved ONCE in `resolveAuthzContext`
|
|
1796
|
+
* (`PLATFORM_ADMIN > TENANT_ADMIN > MEMBER > EXTERNAL`). This module owns two
|
|
1797
|
+
* things and deliberately nothing more:
|
|
1798
|
+
*
|
|
1799
|
+
* 1. **Derivation (D3).** {@link derivePosture} maps held *capability grants*
|
|
1800
|
+
* — never a better-auth role — to a rung. `PLATFORM_ADMIN` derives from the
|
|
1801
|
+
* unscoped `admin_full_access` grant (the `viewAllRecords`/`modifyAllRecords`
|
|
1802
|
+
* evidence the superuser bypass already trusts); `TENANT_ADMIN` from the
|
|
1803
|
+
* `organization_admin` grant. The better-auth `role='admin'` is upstream a
|
|
1804
|
+
* *provisioning source* of those grants (`auto-org-admin-grant.ts`), so it
|
|
1805
|
+
* never re-enters adjudication here — the #2836 dual-track class is closed
|
|
1806
|
+
* by construction.
|
|
1807
|
+
*
|
|
1808
|
+
* 2. **The rung → injection-rule mapping + its tested invariants (D2).** Each
|
|
1809
|
+
* rung maps to EXACTLY ONE row-visibility injection rule
|
|
1810
|
+
* ({@link POSTURE_INJECTION_RULE}). {@link postureVisibleRows} is the
|
|
1811
|
+
* REFERENCE MODEL of those rules over a synthetic row-set — it locks the two
|
|
1812
|
+
* properties the ADR requires as invariants: strict nesting (rung n's
|
|
1813
|
+
* visible set ⊇ rung n−1's) and the EXTERNAL deny-by-default semantics
|
|
1814
|
+
* (explicit shares only, OWD never widens it).
|
|
1815
|
+
*
|
|
1816
|
+
* This module is NOT the enforcement path. The effective read/write filter is
|
|
1817
|
+
* `Layer0(tenant) AND Layer1(business RLS)`, computed in `@objectstack/plugin-
|
|
1818
|
+
* security` (`tenant-layer.ts` + `security-plugin.ts`), and the real behavior
|
|
1819
|
+
* guard is the `authz-matrix-gate` unit snapshot + the dogfood conformance
|
|
1820
|
+
* matrix. The reference model here exists so the ladder's *mathematical*
|
|
1821
|
+
* properties can be asserted at the unit layer without an enforcement boot, and
|
|
1822
|
+
* so the EXTERNAL rung — which has no enforcement path yet — cannot be
|
|
1823
|
+
* reinvented differently when portal/external membership arrives.
|
|
1824
|
+
*/
|
|
1825
|
+
|
|
1826
|
+
/**
|
|
1827
|
+
* The rung ordering, high privilege → low, matching the spec enum's numeric
|
|
1828
|
+
* values (`PLATFORM_ADMIN=3 … EXTERNAL=0`). Visibility grows monotonically UP
|
|
1829
|
+
* this ladder (see {@link postureVisibleRows}).
|
|
1830
|
+
*/
|
|
1831
|
+
declare const POSTURE_LADDER: readonly ["PLATFORM_ADMIN", "TENANT_ADMIN", "MEMBER", "EXTERNAL"];
|
|
1832
|
+
/** Numeric rank per rung (mirrors the spec `AuthzPosture` enum values). */
|
|
1833
|
+
declare const POSTURE_RANK: Record<AuthzPosture, number>;
|
|
1834
|
+
/**
|
|
1835
|
+
* The ONE row-visibility injection rule each rung maps to (ADR-0095 D2). Prose,
|
|
1836
|
+
* because the machine artifacts live in enforcement (Layer 0 + the per-rung
|
|
1837
|
+
* Layer 1 rule); this is the enumerable contract the explain track reports and
|
|
1838
|
+
* {@link postureVisibleRows} models.
|
|
1839
|
+
*/
|
|
1840
|
+
declare const POSTURE_INJECTION_RULE: Record<AuthzPosture, string>;
|
|
1841
|
+
/** Capability-grant evidence the posture derivation consumes (ADR-0095 D3). */
|
|
1842
|
+
interface PostureEvidence {
|
|
1843
|
+
/**
|
|
1844
|
+
* Holds the UNSCOPED platform-admin capability grant (`admin_full_access` →
|
|
1845
|
+
* `viewAllRecords`/`modifyAllRecords`) — the same evidence the superuser
|
|
1846
|
+
* bypass trusts. NOT a better-auth role.
|
|
1847
|
+
*/
|
|
1848
|
+
isPlatformAdmin: boolean;
|
|
1849
|
+
/**
|
|
1850
|
+
* Holds the org-admin capability grant (`organization_admin`, tenant-scoped
|
|
1851
|
+
* `viewAllRecords`/`modifyAllRecords`). Provisioned from the better-auth
|
|
1852
|
+
* owner/admin role upstream, consumed here only as a held capability.
|
|
1853
|
+
*/
|
|
1854
|
+
isTenantAdmin: boolean;
|
|
1855
|
+
}
|
|
1856
|
+
/**
|
|
1857
|
+
* Resolve the principal's posture rung from held capability grants (ADR-0095 D3).
|
|
1858
|
+
*
|
|
1859
|
+
* Returns `PLATFORM_ADMIN` | `TENANT_ADMIN` | `MEMBER`. It NEVER returns
|
|
1860
|
+
* `EXTERNAL`: no external principal type exists yet (the sharing chain has no
|
|
1861
|
+
* portal/guest-share concept — ADR-0095 W4). The `EXTERNAL` rung, its injection
|
|
1862
|
+
* rule, and its semantics are defined and test-locked ({@link postureVisibleRows},
|
|
1863
|
+
* {@link POSTURE_INJECTION_RULE}) so that when portal/external membership lands
|
|
1864
|
+
* (ADR-0093) the derivation gains an EXTERNAL branch HERE without the rung being
|
|
1865
|
+
* reinvented. `MEMBER` is the authenticated-principal floor.
|
|
1866
|
+
*/
|
|
1867
|
+
declare function derivePosture(evidence: PostureEvidence): AuthzPosture;
|
|
1868
|
+
/** A synthetic record for the ladder reference model. */
|
|
1869
|
+
interface LadderRow {
|
|
1870
|
+
id: string;
|
|
1871
|
+
/** The row's tenant. `undefined` = a non-tenant (platform-global) row. */
|
|
1872
|
+
organization_id?: string;
|
|
1873
|
+
/** The row's owner (drives the MEMBER ownership disjunct). */
|
|
1874
|
+
owner_id?: string;
|
|
1875
|
+
/**
|
|
1876
|
+
* Whether an OWD-derived source would admit this row for a member (public
|
|
1877
|
+
* baseline / criteria sharing). EXTERNAL deliberately ignores this field.
|
|
1878
|
+
*/
|
|
1879
|
+
owdVisible?: boolean;
|
|
1880
|
+
/** User ids this row is EXPLICITLY shared to (the only EXTERNAL source). */
|
|
1881
|
+
sharedTo?: readonly string[];
|
|
1882
|
+
}
|
|
1883
|
+
/** The principal the reference model evaluates a rung for. */
|
|
1884
|
+
interface LadderPrincipal {
|
|
1885
|
+
userId: string;
|
|
1886
|
+
/** The principal's active organization (undefined for an unscoped principal). */
|
|
1887
|
+
organizationId?: string;
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* Reference model of the per-rung injection rule: the visible-row set a rung
|
|
1891
|
+
* would resolve to over `rows` for `principal`. Used to lock the ADR-0095 D2
|
|
1892
|
+
* invariants (strict nesting + EXTERNAL deny-by-default). NOT an enforcement
|
|
1893
|
+
* path — see the module header.
|
|
1894
|
+
*/
|
|
1895
|
+
declare function postureVisibleRows(posture: AuthzPosture, rows: readonly LadderRow[], principal: LadderPrincipal): LadderRow[];
|
|
1896
|
+
|
|
1781
1897
|
/**
|
|
1782
1898
|
* ADR-0069 — authentication-policy session gate.
|
|
1783
1899
|
*
|
|
@@ -2394,4 +2510,4 @@ declare class NamespaceResolver {
|
|
|
2394
2510
|
private suggestAlternative;
|
|
2395
2511
|
}
|
|
2396
2512
|
|
|
2397
|
-
export { API_KEY_PREFIX, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry };
|
|
2513
|
+
export { API_KEY_PREFIX, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { ConflictResolutionStrategy, ApiRegistryEntryInput, ApiRegistryEntry, Ap
|
|
|
8
8
|
import * as QA from '@objectstack/spec/qa';
|
|
9
9
|
import { KeyObject } from 'node:crypto';
|
|
10
10
|
import { PluginCapability, PluginPermissions as PluginPermissions$1, PluginPermissionSet, ResourceType, PermissionAction, PluginPermission, SandboxConfig, KernelSecurityScanResult, KernelSecurityVulnerability, PluginHealthCheck, PluginHealthStatus as PluginHealthStatus$1, PluginHealthReport, HotReloadConfig, VersionConstraint, DependencyConflict, SemanticVersion, CompatibilityLevel } from '@objectstack/spec/kernel';
|
|
11
|
+
import { AuthzPosture } from '@objectstack/spec/security';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Service Lifecycle Types
|
|
@@ -1739,6 +1740,16 @@ interface ResolvedAuthzContext {
|
|
|
1739
1740
|
tabPermissions?: Record<string, 'visible' | 'hidden' | 'default_on' | 'default_off'>;
|
|
1740
1741
|
/** Fellow-org user IDs for RLS scoping of identity tables (`id IN (...)`). */
|
|
1741
1742
|
org_user_ids: string[];
|
|
1743
|
+
/**
|
|
1744
|
+
* [ADR-0095 D2/D3] The monotonic posture rung this principal resolves to,
|
|
1745
|
+
* DERIVED once here from held capability grants (never a better-auth role):
|
|
1746
|
+
* `PLATFORM_ADMIN` (unscoped `admin_full_access`) > `TENANT_ADMIN`
|
|
1747
|
+
* (`organization_admin`) > `MEMBER` (the authenticated floor). `EXTERNAL` is
|
|
1748
|
+
* defined/test-locked but never resolved yet (no external principal type —
|
|
1749
|
+
* see `posture-ladder.ts`). Present only for an authenticated principal;
|
|
1750
|
+
* anonymous requests carry no rung.
|
|
1751
|
+
*/
|
|
1752
|
+
posture?: AuthzPosture;
|
|
1742
1753
|
}
|
|
1743
1754
|
interface ResolveAuthzInput {
|
|
1744
1755
|
/** Data engine (ObjectQL) exposing `find(object, { where, limit, context })`. */
|
|
@@ -1778,6 +1789,111 @@ declare function resolveLocalizationContext(input: ResolveLocalizationInput): Pr
|
|
|
1778
1789
|
currency?: string;
|
|
1779
1790
|
}>;
|
|
1780
1791
|
|
|
1792
|
+
/**
|
|
1793
|
+
* ── The monotonic posture ladder (ADR-0095 D2/D3) ───────────────────────────
|
|
1794
|
+
*
|
|
1795
|
+
* The principal-tiering enum resolved ONCE in `resolveAuthzContext`
|
|
1796
|
+
* (`PLATFORM_ADMIN > TENANT_ADMIN > MEMBER > EXTERNAL`). This module owns two
|
|
1797
|
+
* things and deliberately nothing more:
|
|
1798
|
+
*
|
|
1799
|
+
* 1. **Derivation (D3).** {@link derivePosture} maps held *capability grants*
|
|
1800
|
+
* — never a better-auth role — to a rung. `PLATFORM_ADMIN` derives from the
|
|
1801
|
+
* unscoped `admin_full_access` grant (the `viewAllRecords`/`modifyAllRecords`
|
|
1802
|
+
* evidence the superuser bypass already trusts); `TENANT_ADMIN` from the
|
|
1803
|
+
* `organization_admin` grant. The better-auth `role='admin'` is upstream a
|
|
1804
|
+
* *provisioning source* of those grants (`auto-org-admin-grant.ts`), so it
|
|
1805
|
+
* never re-enters adjudication here — the #2836 dual-track class is closed
|
|
1806
|
+
* by construction.
|
|
1807
|
+
*
|
|
1808
|
+
* 2. **The rung → injection-rule mapping + its tested invariants (D2).** Each
|
|
1809
|
+
* rung maps to EXACTLY ONE row-visibility injection rule
|
|
1810
|
+
* ({@link POSTURE_INJECTION_RULE}). {@link postureVisibleRows} is the
|
|
1811
|
+
* REFERENCE MODEL of those rules over a synthetic row-set — it locks the two
|
|
1812
|
+
* properties the ADR requires as invariants: strict nesting (rung n's
|
|
1813
|
+
* visible set ⊇ rung n−1's) and the EXTERNAL deny-by-default semantics
|
|
1814
|
+
* (explicit shares only, OWD never widens it).
|
|
1815
|
+
*
|
|
1816
|
+
* This module is NOT the enforcement path. The effective read/write filter is
|
|
1817
|
+
* `Layer0(tenant) AND Layer1(business RLS)`, computed in `@objectstack/plugin-
|
|
1818
|
+
* security` (`tenant-layer.ts` + `security-plugin.ts`), and the real behavior
|
|
1819
|
+
* guard is the `authz-matrix-gate` unit snapshot + the dogfood conformance
|
|
1820
|
+
* matrix. The reference model here exists so the ladder's *mathematical*
|
|
1821
|
+
* properties can be asserted at the unit layer without an enforcement boot, and
|
|
1822
|
+
* so the EXTERNAL rung — which has no enforcement path yet — cannot be
|
|
1823
|
+
* reinvented differently when portal/external membership arrives.
|
|
1824
|
+
*/
|
|
1825
|
+
|
|
1826
|
+
/**
|
|
1827
|
+
* The rung ordering, high privilege → low, matching the spec enum's numeric
|
|
1828
|
+
* values (`PLATFORM_ADMIN=3 … EXTERNAL=0`). Visibility grows monotonically UP
|
|
1829
|
+
* this ladder (see {@link postureVisibleRows}).
|
|
1830
|
+
*/
|
|
1831
|
+
declare const POSTURE_LADDER: readonly ["PLATFORM_ADMIN", "TENANT_ADMIN", "MEMBER", "EXTERNAL"];
|
|
1832
|
+
/** Numeric rank per rung (mirrors the spec `AuthzPosture` enum values). */
|
|
1833
|
+
declare const POSTURE_RANK: Record<AuthzPosture, number>;
|
|
1834
|
+
/**
|
|
1835
|
+
* The ONE row-visibility injection rule each rung maps to (ADR-0095 D2). Prose,
|
|
1836
|
+
* because the machine artifacts live in enforcement (Layer 0 + the per-rung
|
|
1837
|
+
* Layer 1 rule); this is the enumerable contract the explain track reports and
|
|
1838
|
+
* {@link postureVisibleRows} models.
|
|
1839
|
+
*/
|
|
1840
|
+
declare const POSTURE_INJECTION_RULE: Record<AuthzPosture, string>;
|
|
1841
|
+
/** Capability-grant evidence the posture derivation consumes (ADR-0095 D3). */
|
|
1842
|
+
interface PostureEvidence {
|
|
1843
|
+
/**
|
|
1844
|
+
* Holds the UNSCOPED platform-admin capability grant (`admin_full_access` →
|
|
1845
|
+
* `viewAllRecords`/`modifyAllRecords`) — the same evidence the superuser
|
|
1846
|
+
* bypass trusts. NOT a better-auth role.
|
|
1847
|
+
*/
|
|
1848
|
+
isPlatformAdmin: boolean;
|
|
1849
|
+
/**
|
|
1850
|
+
* Holds the org-admin capability grant (`organization_admin`, tenant-scoped
|
|
1851
|
+
* `viewAllRecords`/`modifyAllRecords`). Provisioned from the better-auth
|
|
1852
|
+
* owner/admin role upstream, consumed here only as a held capability.
|
|
1853
|
+
*/
|
|
1854
|
+
isTenantAdmin: boolean;
|
|
1855
|
+
}
|
|
1856
|
+
/**
|
|
1857
|
+
* Resolve the principal's posture rung from held capability grants (ADR-0095 D3).
|
|
1858
|
+
*
|
|
1859
|
+
* Returns `PLATFORM_ADMIN` | `TENANT_ADMIN` | `MEMBER`. It NEVER returns
|
|
1860
|
+
* `EXTERNAL`: no external principal type exists yet (the sharing chain has no
|
|
1861
|
+
* portal/guest-share concept — ADR-0095 W4). The `EXTERNAL` rung, its injection
|
|
1862
|
+
* rule, and its semantics are defined and test-locked ({@link postureVisibleRows},
|
|
1863
|
+
* {@link POSTURE_INJECTION_RULE}) so that when portal/external membership lands
|
|
1864
|
+
* (ADR-0093) the derivation gains an EXTERNAL branch HERE without the rung being
|
|
1865
|
+
* reinvented. `MEMBER` is the authenticated-principal floor.
|
|
1866
|
+
*/
|
|
1867
|
+
declare function derivePosture(evidence: PostureEvidence): AuthzPosture;
|
|
1868
|
+
/** A synthetic record for the ladder reference model. */
|
|
1869
|
+
interface LadderRow {
|
|
1870
|
+
id: string;
|
|
1871
|
+
/** The row's tenant. `undefined` = a non-tenant (platform-global) row. */
|
|
1872
|
+
organization_id?: string;
|
|
1873
|
+
/** The row's owner (drives the MEMBER ownership disjunct). */
|
|
1874
|
+
owner_id?: string;
|
|
1875
|
+
/**
|
|
1876
|
+
* Whether an OWD-derived source would admit this row for a member (public
|
|
1877
|
+
* baseline / criteria sharing). EXTERNAL deliberately ignores this field.
|
|
1878
|
+
*/
|
|
1879
|
+
owdVisible?: boolean;
|
|
1880
|
+
/** User ids this row is EXPLICITLY shared to (the only EXTERNAL source). */
|
|
1881
|
+
sharedTo?: readonly string[];
|
|
1882
|
+
}
|
|
1883
|
+
/** The principal the reference model evaluates a rung for. */
|
|
1884
|
+
interface LadderPrincipal {
|
|
1885
|
+
userId: string;
|
|
1886
|
+
/** The principal's active organization (undefined for an unscoped principal). */
|
|
1887
|
+
organizationId?: string;
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* Reference model of the per-rung injection rule: the visible-row set a rung
|
|
1891
|
+
* would resolve to over `rows` for `principal`. Used to lock the ADR-0095 D2
|
|
1892
|
+
* invariants (strict nesting + EXTERNAL deny-by-default). NOT an enforcement
|
|
1893
|
+
* path — see the module header.
|
|
1894
|
+
*/
|
|
1895
|
+
declare function postureVisibleRows(posture: AuthzPosture, rows: readonly LadderRow[], principal: LadderPrincipal): LadderRow[];
|
|
1896
|
+
|
|
1781
1897
|
/**
|
|
1782
1898
|
* ADR-0069 — authentication-policy session gate.
|
|
1783
1899
|
*
|
|
@@ -2394,4 +2510,4 @@ declare class NamespaceResolver {
|
|
|
2394
2510
|
private suggestAlternative;
|
|
2395
2511
|
}
|
|
2396
2512
|
|
|
2397
|
-
export { API_KEY_PREFIX, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry };
|
|
2513
|
+
export { API_KEY_PREFIX, type ApiKeyPrincipal, ApiRegistry, type ApiRegistryPluginConfig, type AuthGate, type BulkWriteOptions, type BulkWriteRowResult, CORE_FALLBACK_FACTORIES, type CalendarParts, DependencyResolver, type GeneratedApiKey, type GrantValidityWindow, HotReloadManager, type KernelState, type KeyInput, type LadderPrincipal, type LadderRow, LiteKernel, type NamespaceCheckResult, type NamespaceConflict, type NamespaceEntry, NamespaceResolver, ObjectKernel, ObjectKernelBase, type ObjectKernelConfig, ObjectLogger, POSTURE_INJECTION_RULE, POSTURE_LADDER, POSTURE_RANK, type ParsedSignature, type PermissionCheckResult$1 as PermissionCheckResult, type PermissionGrant, type Plugin, type PluginArtifactVerifyResult, PluginConfigValidator, type PluginContext, PluginHealthMonitor, type PluginHealthStatus, type PluginLoadResult, PluginLoader, type PluginMetadata, type PermissionCheckResult as PluginPermissionCheckResult, PluginPermissionEnforcer, PluginPermissionManager, type PluginPermissions, PluginSandboxRuntime, PluginSecurityScanner, type PluginSignatureConfig, PluginSignatureVerifier, type PluginStartupResult, type PostureEvidence, type PublisherVerifyResult, index as QA, type ResolveAuthzInput, type ResolveLocalizationInput, type ResolvedAuthzContext, type ResourceUsage, type RetryOptions, SIGNATURE_ALG, type SandboxContext, type ScanTarget, SecurePluginContext, type SecurityIssue, SemanticVersionManager, type ServiceFactory, ServiceLifecycle, type ServiceRegistration, type SignatureVerificationResult, type VersionCompatibility, buildPermissionsFromGrants, bulkWrite, calendarPartsInTz, calendarPartsInTzOrUtc, counterSignPayload, createApiRegistryPlugin, createMemoryCache, createMemoryI18n, createMemoryJob, createMemoryMetadata, createMemoryQueue, createPluginConfigValidator, createPluginPermissionEnforcer, deepMerge, defaultIsTransientError, derivePosture, evaluateAuthGate, extractApiKey, generateApiKey, generateEd25519KeyPair, getEnv, getMemoryUsage, hashApiKey, isAuthGateAllowlisted, isExpired, isGrantActive, isGrantExpired, isNode, parseScopes, parseSignature, postureVisibleRows, readAuthoredTranslationLayer, resolveApiKeyPrincipal, resolveAuthzContext, resolveLocale, resolveLocalizationContext, safeExit, signPayload, verifyPayload, verifyPlatformSignature, verifyPluginArtifact, verifyPublisherSignature, wireAuthoredTranslationSync, withTransientRetry };
|
package/dist/index.js
CHANGED
|
@@ -4136,7 +4136,8 @@ function safeJsonParse(s, fallback) {
|
|
|
4136
4136
|
import {
|
|
4137
4137
|
mapMembershipRole,
|
|
4138
4138
|
BUILTIN_IDENTITY_PLATFORM_ADMIN,
|
|
4139
|
-
ADMIN_FULL_ACCESS
|
|
4139
|
+
ADMIN_FULL_ACCESS,
|
|
4140
|
+
ORGANIZATION_ADMIN
|
|
4140
4141
|
} from "@objectstack/spec";
|
|
4141
4142
|
|
|
4142
4143
|
// src/security/grant-validity.ts
|
|
@@ -4164,6 +4165,62 @@ function isGrantExpired(row, nowMs) {
|
|
|
4164
4165
|
return !(nowMs < until);
|
|
4165
4166
|
}
|
|
4166
4167
|
|
|
4168
|
+
// src/security/posture-ladder.ts
|
|
4169
|
+
var POSTURE_LADDER = [
|
|
4170
|
+
"PLATFORM_ADMIN",
|
|
4171
|
+
"TENANT_ADMIN",
|
|
4172
|
+
"MEMBER",
|
|
4173
|
+
"EXTERNAL"
|
|
4174
|
+
];
|
|
4175
|
+
var POSTURE_RANK = {
|
|
4176
|
+
PLATFORM_ADMIN: 3,
|
|
4177
|
+
TENANT_ADMIN: 2,
|
|
4178
|
+
MEMBER: 1,
|
|
4179
|
+
EXTERNAL: 0
|
|
4180
|
+
};
|
|
4181
|
+
var POSTURE_INJECTION_RULE = {
|
|
4182
|
+
PLATFORM_ADMIN: "Layer 0 exemption where the object posture permits (private / platform-global / better-auth-managed) \u2014 crosses the tenant wall; org-scoped like TENANT_ADMIN on ordinary tenant business objects.",
|
|
4183
|
+
TENANT_ADMIN: "All rows within the active organization (organization_id == ctx.tenantId); no ownership / depth / sharing narrowing.",
|
|
4184
|
+
MEMBER: "Business RLS within the organization \u2014 ownership (owner / unit depth), the OWD baseline, and explicit sharing.",
|
|
4185
|
+
EXTERNAL: "Explicitly shared rows ONLY \u2014 OWD baselines and sharing rules never apply; a misconfiguration can only shrink visibility, never widen it."
|
|
4186
|
+
};
|
|
4187
|
+
function derivePosture(evidence) {
|
|
4188
|
+
if (evidence.isPlatformAdmin) return "PLATFORM_ADMIN";
|
|
4189
|
+
if (evidence.isTenantAdmin) return "TENANT_ADMIN";
|
|
4190
|
+
return "MEMBER";
|
|
4191
|
+
}
|
|
4192
|
+
function isSharedTo(row, userId) {
|
|
4193
|
+
return (row.sharedTo ?? []).includes(userId);
|
|
4194
|
+
}
|
|
4195
|
+
function externalVisible(rows, p) {
|
|
4196
|
+
return rows.filter((r) => isSharedTo(r, p.userId));
|
|
4197
|
+
}
|
|
4198
|
+
function memberVisible(rows, p) {
|
|
4199
|
+
const shared = new Set(externalVisible(rows, p));
|
|
4200
|
+
return rows.filter(
|
|
4201
|
+
(r) => shared.has(r) || r.organization_id === p.organizationId && (r.owner_id === p.userId || r.owdVisible === true)
|
|
4202
|
+
);
|
|
4203
|
+
}
|
|
4204
|
+
function tenantAdminVisible(rows, p) {
|
|
4205
|
+
const member = new Set(memberVisible(rows, p));
|
|
4206
|
+
return rows.filter((r) => member.has(r) || r.organization_id === p.organizationId);
|
|
4207
|
+
}
|
|
4208
|
+
function platformAdminVisible(rows) {
|
|
4209
|
+
return [...rows];
|
|
4210
|
+
}
|
|
4211
|
+
function postureVisibleRows(posture, rows, principal) {
|
|
4212
|
+
switch (posture) {
|
|
4213
|
+
case "PLATFORM_ADMIN":
|
|
4214
|
+
return platformAdminVisible(rows);
|
|
4215
|
+
case "TENANT_ADMIN":
|
|
4216
|
+
return tenantAdminVisible(rows, principal);
|
|
4217
|
+
case "MEMBER":
|
|
4218
|
+
return memberVisible(rows, principal);
|
|
4219
|
+
case "EXTERNAL":
|
|
4220
|
+
return externalVisible(rows, principal);
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
|
|
4167
4224
|
// src/security/resolve-authz-context.ts
|
|
4168
4225
|
function safeJsonParse2(s, fallback) {
|
|
4169
4226
|
try {
|
|
@@ -4310,6 +4367,10 @@ async function resolveAuthzContext(input) {
|
|
|
4310
4367
|
if (hasPlatformAdminGrant && !ctx.positions.includes(BUILTIN_IDENTITY_PLATFORM_ADMIN)) {
|
|
4311
4368
|
ctx.positions.unshift(BUILTIN_IDENTITY_PLATFORM_ADMIN);
|
|
4312
4369
|
}
|
|
4370
|
+
ctx.posture = derivePosture({
|
|
4371
|
+
isPlatformAdmin: hasPlatformAdminGrant,
|
|
4372
|
+
isTenantAdmin: ctx.permissions.includes(ORGANIZATION_ADMIN)
|
|
4373
|
+
});
|
|
4313
4374
|
if (!ctx.permissions.includes("ai_seat")) {
|
|
4314
4375
|
const aiAccess = (await getUserRow())?.ai_access;
|
|
4315
4376
|
if (aiAccess === true || aiAccess === 1 || aiAccess === "1") ctx.permissions.push("ai_seat");
|
|
@@ -5425,6 +5486,9 @@ export {
|
|
|
5425
5486
|
ObjectKernel,
|
|
5426
5487
|
ObjectKernelBase,
|
|
5427
5488
|
ObjectLogger,
|
|
5489
|
+
POSTURE_INJECTION_RULE,
|
|
5490
|
+
POSTURE_LADDER,
|
|
5491
|
+
POSTURE_RANK,
|
|
5428
5492
|
PluginConfigValidator,
|
|
5429
5493
|
PluginHealthMonitor,
|
|
5430
5494
|
PluginLoader,
|
|
@@ -5454,6 +5518,7 @@ export {
|
|
|
5454
5518
|
createPluginPermissionEnforcer,
|
|
5455
5519
|
deepMerge,
|
|
5456
5520
|
defaultIsTransientError,
|
|
5521
|
+
derivePosture,
|
|
5457
5522
|
evaluateAuthGate,
|
|
5458
5523
|
extractApiKey,
|
|
5459
5524
|
generateApiKey,
|
|
@@ -5468,6 +5533,7 @@ export {
|
|
|
5468
5533
|
isNode,
|
|
5469
5534
|
parseScopes,
|
|
5470
5535
|
parseSignature,
|
|
5536
|
+
postureVisibleRows,
|
|
5471
5537
|
readAuthoredTranslationLayer,
|
|
5472
5538
|
resolveApiKeyPrincipal,
|
|
5473
5539
|
resolveAuthzContext,
|