@astram/guard 0.4.1 → 0.5.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/auth/auth.module.d.ts +6 -0
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +106 -15
- package/dist/auth/tokens.d.ts +9 -0
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +10 -1
- package/dist/authentication/log-email-sender.d.ts +13 -0
- package/dist/authentication/log-email-sender.d.ts.map +1 -0
- package/dist/authentication/log-email-sender.js +13 -0
- package/dist/authentication/mariadb-credential-writer.d.ts +16 -0
- package/dist/authentication/mariadb-credential-writer.d.ts.map +1 -0
- package/dist/authentication/mariadb-credential-writer.js +19 -0
- package/dist/authentication/mariadb-mfa-device-store.d.ts +16 -0
- package/dist/authentication/mariadb-mfa-device-store.d.ts.map +1 -0
- package/dist/authentication/mariadb-mfa-device-store.js +99 -0
- package/dist/authentication/mariadb-or-totp-verifier.d.ts +31 -0
- package/dist/authentication/mariadb-or-totp-verifier.d.ts.map +1 -0
- package/dist/authentication/mariadb-or-totp-verifier.js +48 -0
- package/dist/authentication/mariadb-profile-resolver.d.ts +24 -0
- package/dist/authentication/mariadb-profile-resolver.d.ts.map +1 -0
- package/dist/authentication/mariadb-profile-resolver.js +54 -0
- package/dist/authentication/mariadb-profile-writer.d.ts +18 -0
- package/dist/authentication/mariadb-profile-writer.d.ts.map +1 -0
- package/dist/authentication/mariadb-profile-writer.js +36 -0
- package/dist/authentication/mariadb-recovery-code-store.d.ts +47 -0
- package/dist/authentication/mariadb-recovery-code-store.d.ts.map +1 -0
- package/dist/authentication/mariadb-recovery-code-store.js +53 -0
- package/dist/authentication/mariadb-reset-token-store.d.ts +26 -0
- package/dist/authentication/mariadb-reset-token-store.d.ts.map +1 -0
- package/dist/authentication/mariadb-reset-token-store.js +43 -0
- package/dist/authentication/mariadb-session-sweeper.d.ts +33 -0
- package/dist/authentication/mariadb-session-sweeper.d.ts.map +1 -0
- package/dist/authentication/mariadb-session-sweeper.js +60 -0
- package/dist/identity/auth-facts.controller.d.ts +24 -0
- package/dist/identity/auth-facts.controller.d.ts.map +1 -0
- package/dist/identity/auth-facts.controller.js +106 -0
- package/dist/identity/identity-actions.d.ts +22 -0
- package/dist/identity/identity-actions.d.ts.map +1 -0
- package/dist/identity/identity-actions.js +32 -0
- package/dist/identity/module-registry.bridge.d.ts +4 -0
- package/dist/identity/module-registry.bridge.d.ts.map +1 -0
- package/dist/identity/module-registry.bridge.js +43 -0
- package/dist/identity/permission-facts.adapter.d.ts +47 -0
- package/dist/identity/permission-facts.adapter.d.ts.map +1 -0
- package/dist/identity/permission-facts.adapter.js +108 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/migrations-dir.d.ts +2 -0
- package/dist/migrations-dir.d.ts.map +1 -0
- package/dist/migrations-dir.js +13 -0
- package/dist/module/shield-tokens.d.ts +6 -1
- package/dist/module/shield-tokens.d.ts.map +1 -1
- package/dist/module/shield-tokens.js +7 -1
- package/dist/module/shield.module.d.ts +17 -0
- package/dist/module/shield.module.d.ts.map +1 -1
- package/dist/module/shield.module.js +12 -0
- package/migrations/1710000000006-CreateAuthzSchema.cjs +53 -0
- package/migrations/1710000000007-ExtendPermissionAndRolePermission.cjs +66 -0
- package/migrations/1710000000008-CreateAccessBundleTables.cjs +49 -0
- package/package.json +5 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-facts.adapter.d.ts","sourceRoot":"","sources":["../../src/identity/permission-facts.adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AACD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,yFAAyF;AACzF,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,OAAO,SAA8B;CAIlD;AAMD,qBAAa,6BAA6B;IAEtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAHH,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,SAAS,MAAM,EAAE,EACpC,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,GAAG,GAAE,MAAM,MAAiB;IAGzC,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAqB/F,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YASlE,oBAAoB;YAcpB,aAAa;YASb,WAAW;IAQzB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;CAaxB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MariaDbPermissionFactsAdapter — the framework-DEFAULT source of a caller's coarse permission
|
|
4
|
+
* facts, backing `GET /identity/auth-facts` + `/identity/permissions-version`. Reads role ids from
|
|
5
|
+
* the caller's active in-effect postings (`shield_app`), the granted permission keys for those
|
|
6
|
+
* roles (`shield_authz.role_permission`), and the per-tenant permission version
|
|
7
|
+
* (`shield_authz.authz_permission_version`). Projects to `{ action, allowed:true }` facts (an
|
|
8
|
+
* absent fact is the fail-closed deny). A store outage THROWS AuthorizationUnavailableError —
|
|
9
|
+
* never a fabricated empty projection (that would silently read as "you have no grants").
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MariaDbPermissionFactsAdapter = exports.AuthorizationUnavailableError = void 0;
|
|
13
|
+
/** A store/dependency outage while computing facts — the controller maps this to 503. */
|
|
14
|
+
class AuthorizationUnavailableError extends Error {
|
|
15
|
+
constructor(message = 'authorization_unavailable') {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'AuthorizationUnavailableError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.AuthorizationUnavailableError = AuthorizationUnavailableError;
|
|
21
|
+
class MariaDbPermissionFactsAdapter {
|
|
22
|
+
pool;
|
|
23
|
+
listActions;
|
|
24
|
+
controlPlaneKeys;
|
|
25
|
+
now;
|
|
26
|
+
constructor(pool, listActions, controlPlaneKeys, now = Date.now) {
|
|
27
|
+
this.pool = pool;
|
|
28
|
+
this.listActions = listActions;
|
|
29
|
+
this.controlPlaneKeys = controlPlaneKeys;
|
|
30
|
+
this.now = now;
|
|
31
|
+
}
|
|
32
|
+
async projectFor(principalId, tenantId, isRoot) {
|
|
33
|
+
try {
|
|
34
|
+
const roleIds = await this.readRoleIdsForTenant(principalId, tenantId);
|
|
35
|
+
const granted = roleIds.length > 0 ? await this.readGrantKeys(roleIds) : [];
|
|
36
|
+
const expanded = this.expandGrantKeys(granted);
|
|
37
|
+
const keys = isRoot
|
|
38
|
+
? [...new Set([...expanded, ...this.controlPlaneKeys])]
|
|
39
|
+
: expanded;
|
|
40
|
+
const permissionsVersion = await this.readVersion(tenantId);
|
|
41
|
+
return {
|
|
42
|
+
principalId,
|
|
43
|
+
facts: keys.map((action) => ({ action, allowed: true })),
|
|
44
|
+
projectedAt: this.now(),
|
|
45
|
+
permissionsVersion,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err instanceof AuthorizationUnavailableError)
|
|
50
|
+
throw err;
|
|
51
|
+
throw new AuthorizationUnavailableError(err.message);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async currentVersionFor(_principalId, tenantId) {
|
|
55
|
+
try {
|
|
56
|
+
return await this.readVersion(tenantId);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (err instanceof AuthorizationUnavailableError)
|
|
60
|
+
throw err;
|
|
61
|
+
throw new AuthorizationUnavailableError(err.message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async readRoleIdsForTenant(userUuid, companyUuid) {
|
|
65
|
+
const nowMs = this.now();
|
|
66
|
+
const rows = (await this.pool.query(`SELECT DISTINCT mp.mp_role_uuid AS role_uuid
|
|
67
|
+
FROM \`shield_app\`.\`company_membership\` cm
|
|
68
|
+
JOIN \`shield_app\`.\`membership_posting\` mp ON mp.mp_membership_uuid = cm.cm_uuid
|
|
69
|
+
WHERE cm.cm_user_uuid = ? AND cm.cm_company_uuid = ? AND cm.cm_is_active = 1
|
|
70
|
+
AND (mp.mp_effective_from_ms IS NULL OR mp.mp_effective_from_ms <= ?)
|
|
71
|
+
AND (mp.mp_effective_until_ms IS NULL OR mp.mp_effective_until_ms > ?)`, [userUuid, companyUuid, nowMs, nowMs]));
|
|
72
|
+
return rows.map((r) => r.role_uuid);
|
|
73
|
+
}
|
|
74
|
+
async readGrantKeys(roleIds) {
|
|
75
|
+
const placeholders = roleIds.map(() => '?').join(', ');
|
|
76
|
+
const rows = (await this.pool.query(`SELECT rp_perm_key FROM \`shield_authz\`.\`role_permission\` WHERE rp_role_uuid IN (${placeholders})`, [...roleIds]));
|
|
77
|
+
return rows.map((r) => r.rp_perm_key);
|
|
78
|
+
}
|
|
79
|
+
async readVersion(tenantId) {
|
|
80
|
+
const rows = (await this.pool.query('SELECT apv_version FROM `shield_authz`.`authz_permission_version` WHERE apv_tenant_uuid = ? LIMIT 1', [tenantId]));
|
|
81
|
+
return rows[0] !== undefined ? Number(rows[0].apv_version) : 0;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Expand wildcard grant keys against the registry's declared actions:
|
|
85
|
+
* 'identity' / 'identity:*' → every 'identity:' action
|
|
86
|
+
* 'identity:company:*' → every 'identity:company:<action>'
|
|
87
|
+
* Exact keys pass through. Bounded to listActions() so a wildcard can never grant an
|
|
88
|
+
* action that does not exist.
|
|
89
|
+
*/
|
|
90
|
+
expandGrantKeys(grantKeys) {
|
|
91
|
+
const all = this.listActions();
|
|
92
|
+
const out = new Set();
|
|
93
|
+
for (const key of grantKeys) {
|
|
94
|
+
if (key.endsWith(':*') || key.indexOf(':') === -1) {
|
|
95
|
+
const prefix = key.endsWith(':*') ? key.slice(0, -1) : `${key}:`; // 'identity:*'→'identity:' ; 'identity'→'identity:'
|
|
96
|
+
for (const a of all)
|
|
97
|
+
if (a.startsWith(prefix))
|
|
98
|
+
out.add(a);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
if (all.includes(key))
|
|
102
|
+
out.add(key);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return [...out];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.MariaDbPermissionFactsAdapter = MariaDbPermissionFactsAdapter;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
* Depends on `@astram/core` (workspace); PEER-depends on `@nestjs/common`,
|
|
15
15
|
* `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
|
|
16
16
|
*/
|
|
17
|
+
export { guardMigrationsDir } from './migrations-dir.js';
|
|
18
|
+
export { buildIdentityModuleRegistry } from './identity/module-registry.bridge.js';
|
|
19
|
+
export { MODULE_KEY, IDENTITY_ACTIONS, actionsFor } from './identity/identity-actions.js';
|
|
17
20
|
export { ShieldModule, SHIELD_DECISION_AUTHORITY, type ShieldModuleOptions, type ShieldModuleAsyncOptions, type RecordAuthorizationInputs, } from './module/shield.module.js';
|
|
18
21
|
export { Public, Classified, CLASSIFICATION_METADATA, DEFAULT_CLASSIFIED_ACTION, normalizeClassification, } from './enforcement/classification.decorator.js';
|
|
19
22
|
export type { Classification } from './enforcement/classification.decorator.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,8 +16,26 @@
|
|
|
16
16
|
* `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
19
|
+
exports.MariaDbCrossTenantGrantAdapter = exports.makeShareDeleteCascade = exports.ShareStoreUnavailableError = exports.ShareNotPermittedError = exports.SHIELD_RECORD_SHARE_WRITER = exports.RecordShareWriter = exports.SHIELD_RECORD_SHARE_PORT = exports.MariaDbRecordShareAdapter = exports.SHIELD_RECORD_RULE_PORT = exports.MariaDbRecordPermissionRuleAdapter = exports.SHIELD_CLOCK = exports.SHIELD_REFRESH_HASHER = exports.SHIELD_TOKEN_GENERATOR = exports.systemClockProvider = exports.refreshHasherProvider = exports.cryptoTokenGeneratorProvider = exports.SystemClock = exports.Sha256RefreshTokenHasher = exports.CryptoTokenGenerator = exports.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = exports.SHIELD_PASSWORD_HASHER = exports.argon2idHasherProvider = exports.Argon2idPasswordHasher = exports.stubDecisionAuthority = exports.GlobalEnforcementGuard = exports.NO_SESSION_FACTS = exports.SHIELD_SESSION_FACTS_ALS = exports.extractBearerToken = exports.principalFromClaims = exports.resolveRequestPrincipal = exports.SessionTokenBinder = exports.SHIELD_SESSION_TOKEN_BINDER = exports.CatalogGatabilityError = exports.CatalogReconciler = exports.OperationInventoryScanner = exports.normalizeClassification = exports.DEFAULT_CLASSIFIED_ACTION = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = exports.actionsFor = exports.IDENTITY_ACTIONS = exports.MODULE_KEY = exports.buildIdentityModuleRegistry = exports.guardMigrationsDir = void 0;
|
|
20
|
+
exports.buildOtpauthUri = exports.generateTotpSecret = exports.PendingMfaStore = exports.AuthController = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.hmacSha1 = exports.resolveTotpVerifier = exports.makeDefaultTotpVerifier = exports.AuthModule = exports.PersistenceModule = exports.MariaDbCredentialResolver = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_SENDER = exports.SHIELD_RESET_TOKEN_STORE = exports.SHIELD_CREDENTIAL_WRITER = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_PROFILE_RESOLVER = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.SHIELD_DB_POOL = exports.DEFAULT_REDIS_URL = exports.DEFAULT_DB_CONFIG = exports.assertRefreshHmacKey = exports.loadRefreshHmacKey = exports.loadSessionLifetimes = exports.loadRedisConfig = exports.loadDbConfig = exports.SCHEMA_SVC_POOL_HARD_CAP = exports.DEFAULT_POOL_BUDGET = exports.evaluatePoolBudget = exports.loadPoolBudget = exports.loadAppConfig = exports.APP_CONFIG = exports.assertPoolBudget = exports.BootSequence = exports.buildRecordAuthorization = exports.SHIELD_OPERATION_AUTHORITY_PORT = exports.ManifestOperationAuthorityAdapter = exports.GrantStoreUnavailableError = exports.InvalidGrantError = exports.GrantNotPermittedError = exports.SHIELD_CROSS_TENANT_GRANT_WRITER = exports.CrossTenantGrantWriter = exports.SHIELD_CROSS_TENANT_GRANT_PORT = void 0;
|
|
21
|
+
exports.AccountController = exports.generateRecoveryCodes = void 0;
|
|
22
|
+
// Framework authz migrations (shield_authz DDL — permission / role_permission /
|
|
23
|
+
// authz_permission_version). Absolute path a consumer's `@astram/migrate` setup merges in.
|
|
24
|
+
var migrations_dir_js_1 = require("./migrations-dir.js");
|
|
25
|
+
Object.defineProperty(exports, "guardMigrationsDir", { enumerable: true, get: function () { return migrations_dir_js_1.guardMigrationsDir; } });
|
|
26
|
+
// The identity module-registry BRIDGE (engine ObjectTypes → a populated core
|
|
27
|
+
// ModuleRegistry) + the identity action vocabulary. Exported so `@astram/identity`
|
|
28
|
+
// (which depends on `@astram/guard` — the sanctioned graph direction) can build the
|
|
29
|
+
// registry from its OWN `identityObjects` and project the permission-key universe it
|
|
30
|
+
// passes back into `ShieldModule.forRoot({ identityActionKeys, identityControlPlaneKeys })`.
|
|
31
|
+
// Guard NEVER imports `@astram/identity`; the keys reach the auth-facts adapter ONLY as
|
|
32
|
+
// runtime option values the consumer threads in.
|
|
33
|
+
var module_registry_bridge_js_1 = require("./identity/module-registry.bridge.js");
|
|
34
|
+
Object.defineProperty(exports, "buildIdentityModuleRegistry", { enumerable: true, get: function () { return module_registry_bridge_js_1.buildIdentityModuleRegistry; } });
|
|
35
|
+
var identity_actions_js_1 = require("./identity/identity-actions.js");
|
|
36
|
+
Object.defineProperty(exports, "MODULE_KEY", { enumerable: true, get: function () { return identity_actions_js_1.MODULE_KEY; } });
|
|
37
|
+
Object.defineProperty(exports, "IDENTITY_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.IDENTITY_ACTIONS; } });
|
|
38
|
+
Object.defineProperty(exports, "actionsFor", { enumerable: true, get: function () { return identity_actions_js_1.actionsFor; } });
|
|
21
39
|
// The single registration seam.
|
|
22
40
|
var shield_module_js_1 = require("./module/shield.module.js");
|
|
23
41
|
Object.defineProperty(exports, "ShieldModule", { enumerable: true, get: function () { return shield_module_js_1.ShieldModule; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations-dir.d.ts","sourceRoot":"","sources":["../src/migrations-dir.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,kBAAkB,EAAE,MAA4C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.guardMigrationsDir = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Absolute path to the framework authz migration files (`packages/guard/migrations`).
|
|
6
|
+
*
|
|
7
|
+
* The consuming app resolves this (via `@astram/migrate`) to MERGE guard's authz migrations
|
|
8
|
+
* with @astram/identity's + its own. Resolved relative to THIS compiled module's directory:
|
|
9
|
+
* `dist/migrations-dir.js` → `../migrations` (the migrations dir sits beside `dist/`, at the
|
|
10
|
+
* package root, published via package.json `files`).
|
|
11
|
+
*/
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
exports.guardMigrationsDir = (0, node_path_1.join)(__dirname, '..', 'migrations');
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* ADR-0001 decision entry both the global enforcement guard and the engine's
|
|
11
11
|
* permission-gate stage consult. Provided app-wide by `ShieldModule.forRoot()`
|
|
12
12
|
* (default: the deny-by-default stub; overridable via the `decisionAuthority` option).
|
|
13
|
+
*
|
|
14
|
+
* DEFINED IN `@astram/core` and RE-EXPORTED here for back-compat — moved there so
|
|
15
|
+
* `@astram/engine` can consume the same token WITHOUT importing `@astram/guard` (which
|
|
16
|
+
* depends on engine — a guard-local token created an engine ↔ guard cycle). Both packages
|
|
17
|
+
* now import the ONE symbol from core, so it stays a single DI identity across the app.
|
|
13
18
|
*/
|
|
14
|
-
export
|
|
19
|
+
export { SHIELD_DECISION_AUTHORITY } from '@astram/core';
|
|
15
20
|
//# sourceMappingURL=shield-tokens.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-tokens.d.ts","sourceRoot":"","sources":["../../src/module/shield-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH
|
|
1
|
+
{"version":3,"file":"shield-tokens.d.ts","sourceRoot":"","sources":["../../src/module/shield-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -13,5 +13,11 @@ exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
|
13
13
|
* ADR-0001 decision entry both the global enforcement guard and the engine's
|
|
14
14
|
* permission-gate stage consult. Provided app-wide by `ShieldModule.forRoot()`
|
|
15
15
|
* (default: the deny-by-default stub; overridable via the `decisionAuthority` option).
|
|
16
|
+
*
|
|
17
|
+
* DEFINED IN `@astram/core` and RE-EXPORTED here for back-compat — moved there so
|
|
18
|
+
* `@astram/engine` can consume the same token WITHOUT importing `@astram/guard` (which
|
|
19
|
+
* depends on engine — a guard-local token created an engine ↔ guard cycle). Both packages
|
|
20
|
+
* now import the ONE symbol from core, so it stays a single DI identity across the app.
|
|
16
21
|
*/
|
|
17
|
-
|
|
22
|
+
var core_1 = require("@astram/core");
|
|
23
|
+
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return core_1.SHIELD_DECISION_AUTHORITY; } });
|
|
@@ -138,6 +138,14 @@ export interface ShieldModuleOptions {
|
|
|
138
138
|
* `auth: true`.
|
|
139
139
|
*/
|
|
140
140
|
readonly rootIds?: readonly string[];
|
|
141
|
+
/**
|
|
142
|
+
* The identity permission-key universe for the auth-facts projection. Pass
|
|
143
|
+
* `identityAuthActionKeys` from `@astram/identity` when `auth: true` to light up the
|
|
144
|
+
* permission-gated admin nav. Only consulted when `auth: true`.
|
|
145
|
+
*/
|
|
146
|
+
readonly identityActionKeys?: readonly string[];
|
|
147
|
+
/** The control-plane subset — pass `identityControlPlaneKeys` from `@astram/identity`. */
|
|
148
|
+
readonly identityControlPlaneKeys?: readonly string[];
|
|
141
149
|
/**
|
|
142
150
|
* OPTIONAL eager session-facts projector (ADR-0011) — see
|
|
143
151
|
* {@link AuthModuleOptions.sessionFactsProjector}. Threaded straight through to
|
|
@@ -224,6 +232,15 @@ export interface ShieldModuleAsyncOptions {
|
|
|
224
232
|
* then threaded exactly like the static case. Only consulted when `auth: true`.
|
|
225
233
|
*/
|
|
226
234
|
readonly rootIds?: readonly string[];
|
|
235
|
+
/**
|
|
236
|
+
* The identity permission-key universe for the auth-facts projection — see
|
|
237
|
+
* {@link ShieldModuleOptions.identityActionKeys}. STATIC here (like the other seams): a
|
|
238
|
+
* registration-time collaborator threaded into the statically-composed {@link AuthModule}
|
|
239
|
+
* import. Only consulted when `auth: true`.
|
|
240
|
+
*/
|
|
241
|
+
readonly identityActionKeys?: readonly string[];
|
|
242
|
+
/** The control-plane subset — see {@link ShieldModuleOptions.identityControlPlaneKeys}. */
|
|
243
|
+
readonly identityControlPlaneKeys?: readonly string[];
|
|
227
244
|
/**
|
|
228
245
|
* OPTIONAL eager session-facts projector — see {@link ShieldModuleOptions.sessionFactsProjector}.
|
|
229
246
|
* STATIC here (like the other seams): a registration-time collaborator threaded into the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -188,6 +188,12 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
188
188
|
...(options.mfaDeviceStore ? { mfaDeviceStore: options.mfaDeviceStore } : {}),
|
|
189
189
|
...(options.totpVerifier ? { totpVerifier: options.totpVerifier } : {}),
|
|
190
190
|
...(options.rootIds ? { rootIds: options.rootIds } : {}),
|
|
191
|
+
...(options.identityActionKeys
|
|
192
|
+
? { identityActionKeys: options.identityActionKeys }
|
|
193
|
+
: {}),
|
|
194
|
+
...(options.identityControlPlaneKeys
|
|
195
|
+
? { identityControlPlaneKeys: options.identityControlPlaneKeys }
|
|
196
|
+
: {}),
|
|
191
197
|
...(options.sessionFactsProjector
|
|
192
198
|
? { sessionFactsProjector: options.sessionFactsProjector }
|
|
193
199
|
: {}),
|
|
@@ -293,6 +299,12 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
293
299
|
...(options.mfaDeviceStore ? { mfaDeviceStore: options.mfaDeviceStore } : {}),
|
|
294
300
|
...(options.totpVerifier ? { totpVerifier: options.totpVerifier } : {}),
|
|
295
301
|
...(options.rootIds ? { rootIds: options.rootIds } : {}),
|
|
302
|
+
...(options.identityActionKeys
|
|
303
|
+
? { identityActionKeys: options.identityActionKeys }
|
|
304
|
+
: {}),
|
|
305
|
+
...(options.identityControlPlaneKeys
|
|
306
|
+
? { identityControlPlaneKeys: options.identityControlPlaneKeys }
|
|
307
|
+
: {}),
|
|
296
308
|
...(options.sessionFactsProjector
|
|
297
309
|
? { sessionFactsProjector: options.sessionFactsProjector }
|
|
298
310
|
: {}),
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework authz migration — the shield_authz backing tables (empty until now):
|
|
3
|
+
* permission — grantable permission-key catalog.
|
|
4
|
+
* role_permission — role→permission grants (exact OR wildcard key strings).
|
|
5
|
+
* authz_permission_version — per-tenant permission-version counter (ADR-0011 freshness).
|
|
6
|
+
*
|
|
7
|
+
* shield_authz is @astram/guard's OWN schema (its decision adapters read it). Shipped here
|
|
8
|
+
* (not @astram/identity) to keep the package boundary: identity owns the org model, guard owns
|
|
9
|
+
* authz. Literal column names (NOT in the @astram/identity object registry — no reflectObjectType).
|
|
10
|
+
* Idempotent (CREATE TABLE IF NOT EXISTS). No hard-coded UUIDs. Run by the DDL account.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const SCHEMA = 'shield_authz';
|
|
14
|
+
const TS = 'TIMESTAMP(0) NOT NULL DEFAULT CURRENT_TIMESTAMP';
|
|
15
|
+
|
|
16
|
+
async function up({ query }) {
|
|
17
|
+
await query(`CREATE SCHEMA IF NOT EXISTS \`${SCHEMA}\` DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
18
|
+
|
|
19
|
+
// permission — the grantable key catalog (perm_key is the stable identity).
|
|
20
|
+
await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`permission\` (
|
|
21
|
+
perm_key VARCHAR(191) NOT NULL,
|
|
22
|
+
perm_description VARCHAR(255) NULL,
|
|
23
|
+
perm_created_at ${TS},
|
|
24
|
+
PRIMARY KEY (perm_key)
|
|
25
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
26
|
+
|
|
27
|
+
// role_permission — role→permission grants (exact or wildcard key strings).
|
|
28
|
+
await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`role_permission\` (
|
|
29
|
+
rp_uuid VARCHAR(36) NOT NULL,
|
|
30
|
+
rp_role_uuid VARCHAR(36) NOT NULL,
|
|
31
|
+
rp_perm_key VARCHAR(191) NOT NULL,
|
|
32
|
+
rp_created_by VARCHAR(36) NULL,
|
|
33
|
+
rp_created_at ${TS},
|
|
34
|
+
PRIMARY KEY (rp_uuid),
|
|
35
|
+
UNIQUE KEY uq_role_perm (rp_role_uuid, rp_perm_key),
|
|
36
|
+
INDEX idx_rp_role (rp_role_uuid)
|
|
37
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
38
|
+
|
|
39
|
+
// authz_permission_version — per-tenant version counter (ADR-0011 freshness).
|
|
40
|
+
await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`authz_permission_version\` (
|
|
41
|
+
apv_tenant_uuid VARCHAR(36) NOT NULL,
|
|
42
|
+
apv_version BIGINT NOT NULL DEFAULT 0,
|
|
43
|
+
PRIMARY KEY (apv_tenant_uuid)
|
|
44
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function down({ query }) {
|
|
48
|
+
await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`role_permission\``);
|
|
49
|
+
await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`authz_permission_version\``);
|
|
50
|
+
await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`permission\``);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = { up, down };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework authz migration — extends the shield_authz.permission catalog + role_permission
|
|
3
|
+
* grant rows to the full column set the grant-admin service (Phase 4) needs.
|
|
4
|
+
*
|
|
5
|
+
* The framework's `1710000000006-CreateAuthzSchema` created `permission` with only
|
|
6
|
+
* (perm_key, perm_description, perm_created_at) and `role_permission` with
|
|
7
|
+
* (rp_uuid, rp_role_uuid, rp_perm_key, rp_created_by, rp_created_at). This migration is
|
|
8
|
+
* ADDITIVE — it never touches those existing columns — and brings `permission` up to
|
|
9
|
+
* astram3's catalog shape (perm_uuid/module/type_key/action/label/tier + perm_status for the
|
|
10
|
+
* MariaDbCatalogStore contract) and adds `rp_granted_by`/`rp_granted_at` to `role_permission`
|
|
11
|
+
* (the grant-admin service's own attribution columns, alongside the pre-existing rp_created_*).
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: every ADD is `ADD COLUMN IF NOT EXISTS` (MariaDB-supported), so this is a clean
|
|
14
|
+
* no-op against a DB that already has these columns (e.g. astram4's live DB). `perm_uuid` is
|
|
15
|
+
* added as a plain nullable column — NOT a new primary key — since `permission` already has a
|
|
16
|
+
* populated PK (perm_key) and changing the PK of an existing table is out of scope here; the
|
|
17
|
+
* reconciler backfills perm_uuid + the other NOT NULL DEFAULT '' text columns with real values.
|
|
18
|
+
*
|
|
19
|
+
* Literal column names (NOT in the @astram/identity object registry — no reflectObjectType).
|
|
20
|
+
* Run by the DDL account.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const SCHEMA = 'shield_authz';
|
|
24
|
+
|
|
25
|
+
async function up({ query }) {
|
|
26
|
+
// permission — add the catalog columns astram3's MariaDbCatalogStore contract expects.
|
|
27
|
+
await query(
|
|
28
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_uuid VARCHAR(36) NULL`
|
|
29
|
+
);
|
|
30
|
+
await query(
|
|
31
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_module VARCHAR(64) NOT NULL DEFAULT ''`
|
|
32
|
+
);
|
|
33
|
+
await query(
|
|
34
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_type_key VARCHAR(64) NOT NULL DEFAULT ''`
|
|
35
|
+
);
|
|
36
|
+
await query(
|
|
37
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_action VARCHAR(64) NOT NULL DEFAULT ''`
|
|
38
|
+
);
|
|
39
|
+
await query(
|
|
40
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_label VARCHAR(191) NOT NULL DEFAULT ''`
|
|
41
|
+
);
|
|
42
|
+
await query(
|
|
43
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_tier VARCHAR(32) NOT NULL DEFAULT 'gated'`
|
|
44
|
+
);
|
|
45
|
+
await query(
|
|
46
|
+
`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS perm_status VARCHAR(16) NOT NULL DEFAULT 'active'`
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// role_permission — add the grant-admin service's attribution columns (additive; rp_created_*
|
|
50
|
+
// from 006 stays untouched).
|
|
51
|
+
await query(
|
|
52
|
+
`ALTER TABLE \`${SCHEMA}\`.\`role_permission\` ADD COLUMN IF NOT EXISTS rp_granted_by CHAR(36) NULL`
|
|
53
|
+
);
|
|
54
|
+
await query(
|
|
55
|
+
`ALTER TABLE \`${SCHEMA}\`.\`role_permission\` ADD COLUMN IF NOT EXISTS rp_granted_at TIMESTAMP NULL`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function down() {
|
|
60
|
+
// Documented NO-OP: dropping columns here would drop live catalog/grant-attribution data
|
|
61
|
+
// (perm_module/type_key/action/label/tier/status, rp_granted_by/rp_granted_at) with no safe
|
|
62
|
+
// way to reconstruct it. Reversal of this migration, if ever needed, must be a deliberate,
|
|
63
|
+
// reviewed follow-up migration — not an automatic DROP COLUMN in `down()`.
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { up, down };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework authz migration — the access-bundle backing tables in shield_authz:
|
|
3
|
+
* access_bundle — developer-declared, admin-grantable named permission bundles
|
|
4
|
+
* (reconciled from @AccessBundle specs, never seeded here)
|
|
5
|
+
* access_bundle_permission — bundle→atomic-key resolution rows
|
|
6
|
+
*
|
|
7
|
+
* A bundle expands to its atomic `role_permission` keys at grant time; these tables hold only
|
|
8
|
+
* the catalog (the declared bundles + their key sets). No seed rows, no hard-coded UUIDs —
|
|
9
|
+
* bundles are reconciled at boot from the collected declarations.
|
|
10
|
+
*
|
|
11
|
+
* Ported from astram3 `server/migrations/1720000000018-CreateAccessBundleTables.js` (read-only
|
|
12
|
+
* reference — column set, keys, and FK match exactly).
|
|
13
|
+
*
|
|
14
|
+
* Idempotent (CREATE TABLE IF NOT EXISTS). Structural (no tenant gate). Run by the DDL account.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const SCHEMA = 'shield_authz';
|
|
18
|
+
|
|
19
|
+
async function up({ query }) {
|
|
20
|
+
await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`access_bundle\` (
|
|
21
|
+
ab_uuid CHAR(36) NOT NULL,
|
|
22
|
+
ab_key VARCHAR(120) NOT NULL,
|
|
23
|
+
ab_module VARCHAR(60) NOT NULL,
|
|
24
|
+
ab_label VARCHAR(200) NOT NULL,
|
|
25
|
+
ab_description VARCHAR(500) NULL,
|
|
26
|
+
ab_status VARCHAR(16) NOT NULL DEFAULT 'active',
|
|
27
|
+
PRIMARY KEY (ab_uuid),
|
|
28
|
+
UNIQUE KEY UQ_access_bundle_module_key (ab_module, ab_key)
|
|
29
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
30
|
+
|
|
31
|
+
await query(`CREATE TABLE IF NOT EXISTS \`${SCHEMA}\`.\`access_bundle_permission\` (
|
|
32
|
+
abp_uuid CHAR(36) NOT NULL,
|
|
33
|
+
abp_bundle_uuid CHAR(36) NOT NULL,
|
|
34
|
+
abp_perm_key VARCHAR(200) NOT NULL,
|
|
35
|
+
PRIMARY KEY (abp_uuid),
|
|
36
|
+
UNIQUE KEY UQ_abp_bundle_key (abp_bundle_uuid, abp_perm_key),
|
|
37
|
+
CONSTRAINT FK_access_bundle_permission_bundle
|
|
38
|
+
FOREIGN KEY (abp_bundle_uuid) REFERENCES \`${SCHEMA}\`.\`access_bundle\` (ab_uuid)
|
|
39
|
+
ON DELETE CASCADE
|
|
40
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function down({ query }) {
|
|
44
|
+
// FK order: drop the child (access_bundle_permission) before the parent (access_bundle).
|
|
45
|
+
await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle_permission\``);
|
|
46
|
+
await query(`DROP TABLE IF EXISTS \`${SCHEMA}\`.\`access_bundle\``);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = { up, down };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the enforcement guard + real-world adapters (the 'hands'). One global deny-by-default gate every request passes through (ADR-0002), classification decorators, boot-pool assertion (ADR-0018), the forRoot() registration seam, and the DB/Redis/crypto adapters that connect the sealed core to a real backend. Depends on @astram/core (ADR-0003, ADR-0023).",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
|
-
"dist"
|
|
16
|
+
"dist",
|
|
17
|
+
"migrations"
|
|
17
18
|
],
|
|
18
19
|
"sideEffects": false,
|
|
19
20
|
"publishConfig": {
|
|
@@ -23,7 +24,8 @@
|
|
|
23
24
|
"argon2": "^0.41.1",
|
|
24
25
|
"ioredis": "^5.4.1",
|
|
25
26
|
"mariadb": "^3.4.0",
|
|
26
|
-
"@astram/core": "1.0.0"
|
|
27
|
+
"@astram/core": "1.0.0",
|
|
28
|
+
"@astram/engine": "0.1.3"
|
|
27
29
|
},
|
|
28
30
|
"peerDependencies": {
|
|
29
31
|
"@nestjs/common": "^11",
|