@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.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,