@nextera.one/axis-server-sdk 0.8.0 → 0.9.2
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/core/index.d.mts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/index.d.mts +296 -110
- package/dist/index.d.ts +296 -110
- package/dist/index.js +620 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +581 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1368,10 +1368,10 @@ function tlv(type, value) {
|
|
|
1368
1368
|
]);
|
|
1369
1369
|
}
|
|
1370
1370
|
function buildTLVs(items, opts) {
|
|
1371
|
-
const
|
|
1371
|
+
const allow2 = opts?.allowDupTypes ?? /* @__PURE__ */ new Set();
|
|
1372
1372
|
const sorted = [...items].sort((a, b) => a.type - b.type);
|
|
1373
1373
|
for (let i = 1; i < sorted.length; i++) {
|
|
1374
|
-
if (sorted[i].type === sorted[i - 1].type && !
|
|
1374
|
+
if (sorted[i].type === sorted[i - 1].type && !allow2.has(sorted[i].type)) {
|
|
1375
1375
|
throw new Error(`TLV_DUP_TYPE_${sorted[i].type}`);
|
|
1376
1376
|
}
|
|
1377
1377
|
}
|
|
@@ -1941,9 +1941,33 @@ var INTENT_REQUIREMENTS = {
|
|
|
1941
1941
|
"passport.revoke": ["write", "witness"],
|
|
1942
1942
|
"stream.publish": ["write"],
|
|
1943
1943
|
"stream.subscribe": ["read"],
|
|
1944
|
+
// NestFlow intents
|
|
1945
|
+
"auth.web.login.*": ["execute"],
|
|
1946
|
+
"tickauth.challenge.*": ["execute"],
|
|
1947
|
+
"capsule.issue.*": ["write", "execute"],
|
|
1948
|
+
"session.*": ["execute"],
|
|
1949
|
+
"device.list": ["read"],
|
|
1950
|
+
"device.rename": ["write"],
|
|
1951
|
+
"device.trust.*": ["write", "execute"],
|
|
1952
|
+
"device.revoke": ["write", "execute"],
|
|
1953
|
+
"identity.*": ["admin", "execute"],
|
|
1954
|
+
"primary.device.*": ["admin", "execute"],
|
|
1955
|
+
"secret.rotate": ["admin"],
|
|
1956
|
+
"org.security.*": ["admin"],
|
|
1957
|
+
"production.execution.*": ["admin", "execute"],
|
|
1944
1958
|
"admin.*": ["admin"]
|
|
1945
1959
|
};
|
|
1946
1960
|
|
|
1961
|
+
// src/risk/index.ts
|
|
1962
|
+
var RiskDecision = /* @__PURE__ */ ((RiskDecision2) => {
|
|
1963
|
+
RiskDecision2["ALLOW"] = "ALLOW";
|
|
1964
|
+
RiskDecision2["THROTTLE"] = "THROTTLE";
|
|
1965
|
+
RiskDecision2["STEP_UP"] = "STEP_UP";
|
|
1966
|
+
RiskDecision2["WITNESS"] = "WITNESS";
|
|
1967
|
+
RiskDecision2["DENY"] = "DENY";
|
|
1968
|
+
return RiskDecision2;
|
|
1969
|
+
})(RiskDecision || {});
|
|
1970
|
+
|
|
1947
1971
|
// src/core/opcodes.ts
|
|
1948
1972
|
var AXIS_OPCODES = /* @__PURE__ */ new Set([
|
|
1949
1973
|
"CAPSULE.ISSUE",
|
|
@@ -1952,13 +1976,29 @@ var AXIS_OPCODES = /* @__PURE__ */ new Set([
|
|
|
1952
1976
|
"INTENT.EXEC",
|
|
1953
1977
|
"ACTOR.KEY.ROTATE",
|
|
1954
1978
|
"ACTOR.KEY.REVOKE",
|
|
1955
|
-
"ISSUER.KEY.ROTATE"
|
|
1979
|
+
"ISSUER.KEY.ROTATE",
|
|
1980
|
+
// NestFlow opcodes
|
|
1981
|
+
"AUTH.WEB.LOGIN",
|
|
1982
|
+
"AUTH.WEB.SCAN",
|
|
1983
|
+
"TICKAUTH.CREATE",
|
|
1984
|
+
"TICKAUTH.FULFILL",
|
|
1985
|
+
"TICKAUTH.REJECT",
|
|
1986
|
+
"SESSION.ACTIVATE",
|
|
1987
|
+
"SESSION.REFRESH",
|
|
1988
|
+
"SESSION.LOGOUT",
|
|
1989
|
+
"DEVICE.TRUST",
|
|
1990
|
+
"DEVICE.PROMOTE",
|
|
1991
|
+
"DEVICE.REVOKE",
|
|
1992
|
+
"DEVICE.LIST",
|
|
1993
|
+
"DEVICE.RENAME",
|
|
1994
|
+
"IDENTITY.RECOVERY",
|
|
1995
|
+
"IDENTITY.LOCK"
|
|
1956
1996
|
]);
|
|
1957
1997
|
function isKnownOpcode(op) {
|
|
1958
1998
|
return AXIS_OPCODES.has(op);
|
|
1959
1999
|
}
|
|
1960
2000
|
function isAdminOpcode(op) {
|
|
1961
|
-
return op.startsWith("ACTOR.KEY.") || op.startsWith("ISSUER.KEY.");
|
|
2001
|
+
return op.startsWith("ACTOR.KEY.") || op.startsWith("ISSUER.KEY.") || op.startsWith("IDENTITY.");
|
|
1962
2002
|
}
|
|
1963
2003
|
|
|
1964
2004
|
// src/core/receipt.ts
|
|
@@ -2008,7 +2048,42 @@ var INTENT_SENSITIVITY_MAP = {
|
|
|
2008
2048
|
// Admin intents
|
|
2009
2049
|
"admin.create_capsule": 4 /* CRITICAL */,
|
|
2010
2050
|
"admin.revoke_capsule": 4 /* CRITICAL */,
|
|
2011
|
-
"admin.issue_node_cert": 4 /* CRITICAL
|
|
2051
|
+
"admin.issue_node_cert": 4 /* CRITICAL */,
|
|
2052
|
+
// NestFlow: Auth
|
|
2053
|
+
"auth.web.login.request": 2 /* MEDIUM */,
|
|
2054
|
+
"auth.web.login.scan": 3 /* HIGH */,
|
|
2055
|
+
// NestFlow: TickAuth
|
|
2056
|
+
"tickauth.challenge.create": 2 /* MEDIUM */,
|
|
2057
|
+
"tickauth.challenge.fulfill": 3 /* HIGH */,
|
|
2058
|
+
"tickauth.challenge.reject": 2 /* MEDIUM */,
|
|
2059
|
+
// NestFlow: Capsule issuance
|
|
2060
|
+
"capsule.issue.login": 3 /* HIGH */,
|
|
2061
|
+
"capsule.issue.device_registration": 3 /* HIGH */,
|
|
2062
|
+
"capsule.issue.step_up": 3 /* HIGH */,
|
|
2063
|
+
"capsule.issue.recovery": 4 /* CRITICAL */,
|
|
2064
|
+
// NestFlow: Session
|
|
2065
|
+
"session.activate": 3 /* HIGH */,
|
|
2066
|
+
"session.refresh": 2 /* MEDIUM */,
|
|
2067
|
+
"session.logout": 1 /* LOW */,
|
|
2068
|
+
// NestFlow: Device trust
|
|
2069
|
+
"device.trust.request": 3 /* HIGH */,
|
|
2070
|
+
"device.trust.promote": 4 /* CRITICAL */,
|
|
2071
|
+
"device.revoke": 4 /* CRITICAL */,
|
|
2072
|
+
"device.list": 1 /* LOW */,
|
|
2073
|
+
"device.rename": 1 /* LOW */,
|
|
2074
|
+
// NestFlow: Protected operations
|
|
2075
|
+
"flow.publish": 2 /* MEDIUM */,
|
|
2076
|
+
"flow.delete": 3 /* HIGH */,
|
|
2077
|
+
"node.delete": 4 /* CRITICAL */,
|
|
2078
|
+
"secret.rotate": 4 /* CRITICAL */,
|
|
2079
|
+
"org.security.update": 4 /* CRITICAL */,
|
|
2080
|
+
"production.execution.approve": 4 /* CRITICAL */,
|
|
2081
|
+
// NestFlow: Recovery
|
|
2082
|
+
"identity.recovery.start": 4 /* CRITICAL */,
|
|
2083
|
+
"identity.recovery.complete": 4 /* CRITICAL */,
|
|
2084
|
+
"primary.device.rotate": 4 /* CRITICAL */,
|
|
2085
|
+
"identity.lock": 4 /* CRITICAL */,
|
|
2086
|
+
"identity.unlock": 4 /* CRITICAL */
|
|
2012
2087
|
};
|
|
2013
2088
|
function classifyIntent(intent) {
|
|
2014
2089
|
if (INTENT_SENSITIVITY_MAP[intent]) {
|
|
@@ -2063,6 +2138,468 @@ function resolveTimeout(intent) {
|
|
|
2063
2138
|
}
|
|
2064
2139
|
return DEFAULT_TIMEOUT;
|
|
2065
2140
|
}
|
|
2141
|
+
|
|
2142
|
+
// src/core/frame-validator.ts
|
|
2143
|
+
function validateFrameShape(frame) {
|
|
2144
|
+
if (!frame || typeof frame !== "object") {
|
|
2145
|
+
return false;
|
|
2146
|
+
}
|
|
2147
|
+
if (frame.v !== 1) {
|
|
2148
|
+
return false;
|
|
2149
|
+
}
|
|
2150
|
+
const requiredStrings = ["pid", "nonce", "actorId", "opcode"];
|
|
2151
|
+
for (const key of requiredStrings) {
|
|
2152
|
+
if (typeof frame[key] !== "string" || frame[key].length < 6) {
|
|
2153
|
+
return false;
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
if (typeof frame.ts !== "number" || !Number.isFinite(frame.ts)) {
|
|
2157
|
+
return false;
|
|
2158
|
+
}
|
|
2159
|
+
if (frame.aud !== void 0 && (typeof frame.aud !== "string" || frame.aud.length === 0)) {
|
|
2160
|
+
return false;
|
|
2161
|
+
}
|
|
2162
|
+
if (!frame.sig || typeof frame.sig !== "object") {
|
|
2163
|
+
return false;
|
|
2164
|
+
}
|
|
2165
|
+
if (frame.sig.alg !== "EdDSA") {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
if (typeof frame.sig.kid !== "string" || frame.sig.kid.length < 8) {
|
|
2169
|
+
return false;
|
|
2170
|
+
}
|
|
2171
|
+
if (typeof frame.sig.value !== "string" || frame.sig.value.length < 32) {
|
|
2172
|
+
return false;
|
|
2173
|
+
}
|
|
2174
|
+
if (typeof frame.body !== "object" || frame.body === null) {
|
|
2175
|
+
return false;
|
|
2176
|
+
}
|
|
2177
|
+
return true;
|
|
2178
|
+
}
|
|
2179
|
+
function isTimestampValid(ts, skewSeconds = 120) {
|
|
2180
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2181
|
+
const diff = Math.abs(now - ts);
|
|
2182
|
+
return diff <= skewSeconds;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
// src/nestflow/types.ts
|
|
2186
|
+
var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
|
|
2187
|
+
DeviceType2["MOBILE"] = "mobile";
|
|
2188
|
+
DeviceType2["BROWSER"] = "browser";
|
|
2189
|
+
DeviceType2["CLI"] = "cli";
|
|
2190
|
+
DeviceType2["SERVICE"] = "service";
|
|
2191
|
+
return DeviceType2;
|
|
2192
|
+
})(DeviceType || {});
|
|
2193
|
+
var DeviceTrustLevel = /* @__PURE__ */ ((DeviceTrustLevel2) => {
|
|
2194
|
+
DeviceTrustLevel2["PRIMARY"] = "primary";
|
|
2195
|
+
DeviceTrustLevel2["TRUSTED"] = "trusted";
|
|
2196
|
+
DeviceTrustLevel2["EPHEMERAL"] = "ephemeral";
|
|
2197
|
+
return DeviceTrustLevel2;
|
|
2198
|
+
})(DeviceTrustLevel || {});
|
|
2199
|
+
var DeviceStatus = /* @__PURE__ */ ((DeviceStatus2) => {
|
|
2200
|
+
DeviceStatus2["ACTIVE"] = "active";
|
|
2201
|
+
DeviceStatus2["REVOKED"] = "revoked";
|
|
2202
|
+
DeviceStatus2["SUSPENDED"] = "suspended";
|
|
2203
|
+
return DeviceStatus2;
|
|
2204
|
+
})(DeviceStatus || {});
|
|
2205
|
+
var LoginChallengeStatus = /* @__PURE__ */ ((LoginChallengeStatus3) => {
|
|
2206
|
+
LoginChallengeStatus3["PENDING"] = "pending";
|
|
2207
|
+
LoginChallengeStatus3["SCANNED"] = "scanned";
|
|
2208
|
+
LoginChallengeStatus3["APPROVED"] = "approved";
|
|
2209
|
+
LoginChallengeStatus3["REJECTED"] = "rejected";
|
|
2210
|
+
LoginChallengeStatus3["EXPIRED"] = "expired";
|
|
2211
|
+
return LoginChallengeStatus3;
|
|
2212
|
+
})(LoginChallengeStatus || {});
|
|
2213
|
+
var TickAuthChallengeStatus = /* @__PURE__ */ ((TickAuthChallengeStatus2) => {
|
|
2214
|
+
TickAuthChallengeStatus2["PENDING"] = "pending";
|
|
2215
|
+
TickAuthChallengeStatus2["FULFILLED"] = "fulfilled";
|
|
2216
|
+
TickAuthChallengeStatus2["REJECTED"] = "rejected";
|
|
2217
|
+
TickAuthChallengeStatus2["EXPIRED"] = "expired";
|
|
2218
|
+
return TickAuthChallengeStatus2;
|
|
2219
|
+
})(TickAuthChallengeStatus || {});
|
|
2220
|
+
var NestFlowCapsuleType = /* @__PURE__ */ ((NestFlowCapsuleType2) => {
|
|
2221
|
+
NestFlowCapsuleType2["LOGIN"] = "login";
|
|
2222
|
+
NestFlowCapsuleType2["DEVICE_REGISTRATION"] = "device_registration";
|
|
2223
|
+
NestFlowCapsuleType2["STEP_UP"] = "step_up";
|
|
2224
|
+
NestFlowCapsuleType2["RECOVERY"] = "recovery";
|
|
2225
|
+
return NestFlowCapsuleType2;
|
|
2226
|
+
})(NestFlowCapsuleType || {});
|
|
2227
|
+
var CapsuleStatus = /* @__PURE__ */ ((CapsuleStatus2) => {
|
|
2228
|
+
CapsuleStatus2["ACTIVE"] = "active";
|
|
2229
|
+
CapsuleStatus2["CONSUMED"] = "consumed";
|
|
2230
|
+
CapsuleStatus2["REVOKED"] = "revoked";
|
|
2231
|
+
CapsuleStatus2["EXPIRED"] = "expired";
|
|
2232
|
+
return CapsuleStatus2;
|
|
2233
|
+
})(CapsuleStatus || {});
|
|
2234
|
+
var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
|
|
2235
|
+
SessionStatus2["ACTIVE"] = "active";
|
|
2236
|
+
SessionStatus2["EXPIRED"] = "expired";
|
|
2237
|
+
SessionStatus2["REVOKED"] = "revoked";
|
|
2238
|
+
return SessionStatus2;
|
|
2239
|
+
})(SessionStatus || {});
|
|
2240
|
+
var TrustLinkType = /* @__PURE__ */ ((TrustLinkType2) => {
|
|
2241
|
+
TrustLinkType2["LOGIN"] = "login";
|
|
2242
|
+
TrustLinkType2["PROMOTION"] = "promotion";
|
|
2243
|
+
TrustLinkType2["RECOVERY"] = "recovery";
|
|
2244
|
+
return TrustLinkType2;
|
|
2245
|
+
})(TrustLinkType || {});
|
|
2246
|
+
var TrustLinkStatus = /* @__PURE__ */ ((TrustLinkStatus2) => {
|
|
2247
|
+
TrustLinkStatus2["ACTIVE"] = "active";
|
|
2248
|
+
TrustLinkStatus2["REVOKED"] = "revoked";
|
|
2249
|
+
return TrustLinkStatus2;
|
|
2250
|
+
})(TrustLinkStatus || {});
|
|
2251
|
+
var AuthLevel = /* @__PURE__ */ ((AuthLevel2) => {
|
|
2252
|
+
AuthLevel2["SESSION"] = "session";
|
|
2253
|
+
AuthLevel2["SESSION_BROWSER"] = "session_browser";
|
|
2254
|
+
AuthLevel2["STEP_UP"] = "step_up";
|
|
2255
|
+
AuthLevel2["PRIMARY_DEVICE"] = "primary_device";
|
|
2256
|
+
return AuthLevel2;
|
|
2257
|
+
})(AuthLevel || {});
|
|
2258
|
+
|
|
2259
|
+
// src/nestflow/intents.ts
|
|
2260
|
+
var NESTFLOW_INTENTS = {
|
|
2261
|
+
// Auth
|
|
2262
|
+
AUTH_WEB_LOGIN_REQUEST: "auth.web.login.request",
|
|
2263
|
+
AUTH_WEB_LOGIN_SCAN: "auth.web.login.scan",
|
|
2264
|
+
// TickAuth
|
|
2265
|
+
TICKAUTH_CHALLENGE_CREATE: "tickauth.challenge.create",
|
|
2266
|
+
TICKAUTH_CHALLENGE_FULFILL: "tickauth.challenge.fulfill",
|
|
2267
|
+
TICKAUTH_CHALLENGE_REJECT: "tickauth.challenge.reject",
|
|
2268
|
+
// Capsule
|
|
2269
|
+
CAPSULE_ISSUE_LOGIN: "capsule.issue.login",
|
|
2270
|
+
CAPSULE_ISSUE_DEVICE_REGISTRATION: "capsule.issue.device_registration",
|
|
2271
|
+
CAPSULE_ISSUE_STEP_UP: "capsule.issue.step_up",
|
|
2272
|
+
CAPSULE_ISSUE_RECOVERY: "capsule.issue.recovery",
|
|
2273
|
+
// Session
|
|
2274
|
+
SESSION_ACTIVATE: "session.activate",
|
|
2275
|
+
SESSION_REFRESH: "session.refresh",
|
|
2276
|
+
SESSION_LOGOUT: "session.logout",
|
|
2277
|
+
// Device Trust
|
|
2278
|
+
DEVICE_TRUST_REQUEST: "device.trust.request",
|
|
2279
|
+
DEVICE_TRUST_PROMOTE: "device.trust.promote",
|
|
2280
|
+
DEVICE_REVOKE: "device.revoke",
|
|
2281
|
+
DEVICE_LIST: "device.list",
|
|
2282
|
+
DEVICE_RENAME: "device.rename",
|
|
2283
|
+
// Protected Operations
|
|
2284
|
+
FLOW_PUBLISH: "flow.publish",
|
|
2285
|
+
FLOW_DELETE: "flow.delete",
|
|
2286
|
+
NODE_DELETE: "node.delete",
|
|
2287
|
+
SECRET_ROTATE: "secret.rotate",
|
|
2288
|
+
ORG_SECURITY_UPDATE: "org.security.update",
|
|
2289
|
+
PRODUCTION_EXECUTION_APPROVE: "production.execution.approve",
|
|
2290
|
+
// Recovery
|
|
2291
|
+
IDENTITY_RECOVERY_START: "identity.recovery.start",
|
|
2292
|
+
IDENTITY_RECOVERY_COMPLETE: "identity.recovery.complete",
|
|
2293
|
+
PRIMARY_DEVICE_ROTATE: "primary.device.rotate",
|
|
2294
|
+
IDENTITY_LOCK: "identity.lock",
|
|
2295
|
+
IDENTITY_UNLOCK: "identity.unlock"
|
|
2296
|
+
};
|
|
2297
|
+
var NESTFLOW_INTENT_SET = new Set(
|
|
2298
|
+
Object.values(NESTFLOW_INTENTS)
|
|
2299
|
+
);
|
|
2300
|
+
function isNestFlowIntent(intent) {
|
|
2301
|
+
return NESTFLOW_INTENT_SET.has(intent);
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
// src/nestflow/policy-map.ts
|
|
2305
|
+
var NESTFLOW_POLICY_MAP = {
|
|
2306
|
+
// Auth — unauthenticated initiator (session issued after)
|
|
2307
|
+
[NESTFLOW_INTENTS.AUTH_WEB_LOGIN_REQUEST]: "session" /* SESSION */,
|
|
2308
|
+
[NESTFLOW_INTENTS.AUTH_WEB_LOGIN_SCAN]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2309
|
+
// TickAuth — primary device handles challenges
|
|
2310
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_CREATE]: "session" /* SESSION */,
|
|
2311
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_FULFILL]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2312
|
+
[NESTFLOW_INTENTS.TICKAUTH_CHALLENGE_REJECT]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2313
|
+
// Capsule issuance — varies per type
|
|
2314
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_LOGIN]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2315
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_DEVICE_REGISTRATION]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2316
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_STEP_UP]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2317
|
+
[NESTFLOW_INTENTS.CAPSULE_ISSUE_RECOVERY]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2318
|
+
// Session management
|
|
2319
|
+
[NESTFLOW_INTENTS.SESSION_ACTIVATE]: "session" /* SESSION */,
|
|
2320
|
+
[NESTFLOW_INTENTS.SESSION_REFRESH]: "session_browser" /* SESSION_BROWSER */,
|
|
2321
|
+
[NESTFLOW_INTENTS.SESSION_LOGOUT]: "session" /* SESSION */,
|
|
2322
|
+
// Device trust management
|
|
2323
|
+
[NESTFLOW_INTENTS.DEVICE_TRUST_REQUEST]: "session_browser" /* SESSION_BROWSER */,
|
|
2324
|
+
[NESTFLOW_INTENTS.DEVICE_TRUST_PROMOTE]: "step_up" /* STEP_UP */,
|
|
2325
|
+
[NESTFLOW_INTENTS.DEVICE_REVOKE]: "step_up" /* STEP_UP */,
|
|
2326
|
+
[NESTFLOW_INTENTS.DEVICE_LIST]: "session" /* SESSION */,
|
|
2327
|
+
[NESTFLOW_INTENTS.DEVICE_RENAME]: "session_browser" /* SESSION_BROWSER */,
|
|
2328
|
+
// Protected operations — require step-up auth
|
|
2329
|
+
[NESTFLOW_INTENTS.FLOW_PUBLISH]: "session_browser" /* SESSION_BROWSER */,
|
|
2330
|
+
[NESTFLOW_INTENTS.FLOW_DELETE]: "step_up" /* STEP_UP */,
|
|
2331
|
+
[NESTFLOW_INTENTS.NODE_DELETE]: "step_up" /* STEP_UP */,
|
|
2332
|
+
[NESTFLOW_INTENTS.SECRET_ROTATE]: "step_up" /* STEP_UP */,
|
|
2333
|
+
[NESTFLOW_INTENTS.ORG_SECURITY_UPDATE]: "step_up" /* STEP_UP */,
|
|
2334
|
+
[NESTFLOW_INTENTS.PRODUCTION_EXECUTION_APPROVE]: "step_up" /* STEP_UP */,
|
|
2335
|
+
// Recovery — highest privilege
|
|
2336
|
+
[NESTFLOW_INTENTS.IDENTITY_RECOVERY_START]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2337
|
+
[NESTFLOW_INTENTS.IDENTITY_RECOVERY_COMPLETE]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2338
|
+
[NESTFLOW_INTENTS.PRIMARY_DEVICE_ROTATE]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2339
|
+
[NESTFLOW_INTENTS.IDENTITY_LOCK]: "primary_device" /* PRIMARY_DEVICE */,
|
|
2340
|
+
[NESTFLOW_INTENTS.IDENTITY_UNLOCK]: "primary_device" /* PRIMARY_DEVICE */
|
|
2341
|
+
};
|
|
2342
|
+
function getRequiredAuthLevel(intent) {
|
|
2343
|
+
return NESTFLOW_POLICY_MAP[intent];
|
|
2344
|
+
}
|
|
2345
|
+
var AUTH_LEVEL_ORDER = [
|
|
2346
|
+
"session" /* SESSION */,
|
|
2347
|
+
"session_browser" /* SESSION_BROWSER */,
|
|
2348
|
+
"step_up" /* STEP_UP */,
|
|
2349
|
+
"primary_device" /* PRIMARY_DEVICE */
|
|
2350
|
+
];
|
|
2351
|
+
function satisfiesAuthLevel(provided, required) {
|
|
2352
|
+
const providedIdx = AUTH_LEVEL_ORDER.indexOf(provided);
|
|
2353
|
+
const requiredIdx = AUTH_LEVEL_ORDER.indexOf(required);
|
|
2354
|
+
return providedIdx >= requiredIdx;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
// src/nestflow/guards.ts
|
|
2358
|
+
var allow = () => ({ allowed: true });
|
|
2359
|
+
var deny = (reason) => ({ allowed: false, reason });
|
|
2360
|
+
function checkIntentPolicy(intent, currentAuthLevel) {
|
|
2361
|
+
const required = getRequiredAuthLevel(intent);
|
|
2362
|
+
if (!required) {
|
|
2363
|
+
return allow();
|
|
2364
|
+
}
|
|
2365
|
+
if (satisfiesAuthLevel(currentAuthLevel, required)) {
|
|
2366
|
+
return allow();
|
|
2367
|
+
}
|
|
2368
|
+
return {
|
|
2369
|
+
allowed: false,
|
|
2370
|
+
reason: `Intent '${intent}' requires auth level '${required}', got '${currentAuthLevel}'`,
|
|
2371
|
+
step_up_intent: required === "step_up" /* STEP_UP */ ? intent : void 0
|
|
2372
|
+
};
|
|
2373
|
+
}
|
|
2374
|
+
function checkSession(session) {
|
|
2375
|
+
if (!session) {
|
|
2376
|
+
return deny("No session found");
|
|
2377
|
+
}
|
|
2378
|
+
if (session.status !== "active" /* ACTIVE */) {
|
|
2379
|
+
return deny(`Session status is '${session.status}', expected 'active'`);
|
|
2380
|
+
}
|
|
2381
|
+
if (new Date(session.expires_at).getTime() < Date.now()) {
|
|
2382
|
+
return deny("Session has expired");
|
|
2383
|
+
}
|
|
2384
|
+
return allow();
|
|
2385
|
+
}
|
|
2386
|
+
function checkBrowserProof(proof, expectedNonce) {
|
|
2387
|
+
if (!proof) {
|
|
2388
|
+
return deny("Browser proof-of-possession required but not provided");
|
|
2389
|
+
}
|
|
2390
|
+
if (!proof.server_nonce || !proof.signature || !proof.signature_algorithm) {
|
|
2391
|
+
return deny("Browser proof is missing required fields");
|
|
2392
|
+
}
|
|
2393
|
+
if (proof.server_nonce !== expectedNonce) {
|
|
2394
|
+
return deny("Browser proof nonce does not match expected server nonce");
|
|
2395
|
+
}
|
|
2396
|
+
return allow();
|
|
2397
|
+
}
|
|
2398
|
+
var TRUST_ORDER = [
|
|
2399
|
+
"ephemeral" /* EPHEMERAL */,
|
|
2400
|
+
"trusted" /* TRUSTED */,
|
|
2401
|
+
"primary" /* PRIMARY */
|
|
2402
|
+
];
|
|
2403
|
+
function checkDeviceTrust(device, minimumTrust) {
|
|
2404
|
+
if (!device) {
|
|
2405
|
+
return deny("Device not found");
|
|
2406
|
+
}
|
|
2407
|
+
if (device.status !== "active" /* ACTIVE */) {
|
|
2408
|
+
return deny(`Device status is '${device.status}', expected 'active'`);
|
|
2409
|
+
}
|
|
2410
|
+
const deviceIdx = TRUST_ORDER.indexOf(device.trust_level);
|
|
2411
|
+
const requiredIdx = TRUST_ORDER.indexOf(minimumTrust);
|
|
2412
|
+
if (deviceIdx < requiredIdx) {
|
|
2413
|
+
return deny(
|
|
2414
|
+
`Device trust level '${device.trust_level}' does not meet minimum '${minimumTrust}'`
|
|
2415
|
+
);
|
|
2416
|
+
}
|
|
2417
|
+
return allow();
|
|
2418
|
+
}
|
|
2419
|
+
function checkCapsule(capsule, intent, requestingDeviceUid) {
|
|
2420
|
+
if (!capsule) {
|
|
2421
|
+
return deny("Capsule not found");
|
|
2422
|
+
}
|
|
2423
|
+
if (capsule.status !== "active" /* ACTIVE */) {
|
|
2424
|
+
return deny(`Capsule status is '${capsule.status}', expected 'active'`);
|
|
2425
|
+
}
|
|
2426
|
+
if (new Date(capsule.expires_at).getTime() < Date.now()) {
|
|
2427
|
+
return deny("Capsule has expired");
|
|
2428
|
+
}
|
|
2429
|
+
const intentAllowed = capsule.intents.some((pattern) => {
|
|
2430
|
+
if (pattern === "*") return true;
|
|
2431
|
+
if (pattern === intent) return true;
|
|
2432
|
+
if (pattern.endsWith(".*")) {
|
|
2433
|
+
return intent.startsWith(pattern.slice(0, -1));
|
|
2434
|
+
}
|
|
2435
|
+
return false;
|
|
2436
|
+
});
|
|
2437
|
+
if (!intentAllowed) {
|
|
2438
|
+
return deny(`Capsule does not authorize intent '${intent}'`);
|
|
2439
|
+
}
|
|
2440
|
+
if (capsule.device_uid && requestingDeviceUid && capsule.device_uid !== requestingDeviceUid) {
|
|
2441
|
+
return deny("Capsule is bound to a different device");
|
|
2442
|
+
}
|
|
2443
|
+
return allow();
|
|
2444
|
+
}
|
|
2445
|
+
function checkLoginChallenge(challenge, expectedStatus) {
|
|
2446
|
+
if (!challenge) {
|
|
2447
|
+
return deny("Login challenge not found");
|
|
2448
|
+
}
|
|
2449
|
+
if (new Date(challenge.expires_at).getTime() < Date.now()) {
|
|
2450
|
+
return deny("Login challenge has expired");
|
|
2451
|
+
}
|
|
2452
|
+
if (challenge.status !== expectedStatus) {
|
|
2453
|
+
return deny(
|
|
2454
|
+
`Login challenge status is '${challenge.status}', expected '${expectedStatus}'`
|
|
2455
|
+
);
|
|
2456
|
+
}
|
|
2457
|
+
return allow();
|
|
2458
|
+
}
|
|
2459
|
+
function checkTickAuth(challenge) {
|
|
2460
|
+
if (!challenge) {
|
|
2461
|
+
return deny("TickAuth challenge not found");
|
|
2462
|
+
}
|
|
2463
|
+
if (challenge.status !== "pending" /* PENDING */) {
|
|
2464
|
+
return deny(
|
|
2465
|
+
`TickAuth challenge status is '${challenge.status}', expected 'pending'`
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
const now = Date.now();
|
|
2469
|
+
const start = new Date(challenge.tick_window.start).getTime();
|
|
2470
|
+
const end = new Date(challenge.tick_window.end).getTime();
|
|
2471
|
+
if (now < start || now > end) {
|
|
2472
|
+
return deny("TickAuth challenge is outside its tick window");
|
|
2473
|
+
}
|
|
2474
|
+
return allow();
|
|
2475
|
+
}
|
|
2476
|
+
async function checkReplayProtection(nonce, store, windowMs = 5 * 60 * 1e3) {
|
|
2477
|
+
if (!nonce) {
|
|
2478
|
+
return deny("Nonce is required for replay protection");
|
|
2479
|
+
}
|
|
2480
|
+
const seen = await store.has(nonce);
|
|
2481
|
+
if (seen) {
|
|
2482
|
+
return deny("Nonce has already been used (replay detected)");
|
|
2483
|
+
}
|
|
2484
|
+
await store.add(nonce, new Date(Date.now() + windowMs));
|
|
2485
|
+
return allow();
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
// src/nestflow/invariants.ts
|
|
2489
|
+
var LOGIN_CHALLENGE_TRANSITIONS = {
|
|
2490
|
+
["pending" /* PENDING */]: [
|
|
2491
|
+
"scanned" /* SCANNED */,
|
|
2492
|
+
"expired" /* EXPIRED */
|
|
2493
|
+
],
|
|
2494
|
+
["scanned" /* SCANNED */]: [
|
|
2495
|
+
"approved" /* APPROVED */,
|
|
2496
|
+
"rejected" /* REJECTED */,
|
|
2497
|
+
"expired" /* EXPIRED */
|
|
2498
|
+
],
|
|
2499
|
+
["approved" /* APPROVED */]: [],
|
|
2500
|
+
["rejected" /* REJECTED */]: [],
|
|
2501
|
+
["expired" /* EXPIRED */]: []
|
|
2502
|
+
};
|
|
2503
|
+
var TICKAUTH_TRANSITIONS = {
|
|
2504
|
+
["pending" /* PENDING */]: [
|
|
2505
|
+
"fulfilled" /* FULFILLED */,
|
|
2506
|
+
"rejected" /* REJECTED */,
|
|
2507
|
+
"expired" /* EXPIRED */
|
|
2508
|
+
],
|
|
2509
|
+
["fulfilled" /* FULFILLED */]: [],
|
|
2510
|
+
["rejected" /* REJECTED */]: [],
|
|
2511
|
+
["expired" /* EXPIRED */]: []
|
|
2512
|
+
};
|
|
2513
|
+
var CAPSULE_TRANSITIONS = {
|
|
2514
|
+
["active" /* ACTIVE */]: [
|
|
2515
|
+
"consumed" /* CONSUMED */,
|
|
2516
|
+
"revoked" /* REVOKED */,
|
|
2517
|
+
"expired" /* EXPIRED */
|
|
2518
|
+
],
|
|
2519
|
+
["consumed" /* CONSUMED */]: [],
|
|
2520
|
+
["revoked" /* REVOKED */]: [],
|
|
2521
|
+
["expired" /* EXPIRED */]: []
|
|
2522
|
+
};
|
|
2523
|
+
var SESSION_TRANSITIONS = {
|
|
2524
|
+
["active" /* ACTIVE */]: ["expired" /* EXPIRED */, "revoked" /* REVOKED */],
|
|
2525
|
+
["expired" /* EXPIRED */]: [],
|
|
2526
|
+
["revoked" /* REVOKED */]: []
|
|
2527
|
+
};
|
|
2528
|
+
var DEVICE_TRANSITIONS = {
|
|
2529
|
+
["active" /* ACTIVE */]: ["suspended" /* SUSPENDED */, "revoked" /* REVOKED */],
|
|
2530
|
+
["suspended" /* SUSPENDED */]: ["active" /* ACTIVE */, "revoked" /* REVOKED */],
|
|
2531
|
+
["revoked" /* REVOKED */]: []
|
|
2532
|
+
};
|
|
2533
|
+
var TRUST_LINK_TRANSITIONS = {
|
|
2534
|
+
["active" /* ACTIVE */]: ["revoked" /* REVOKED */],
|
|
2535
|
+
["revoked" /* REVOKED */]: []
|
|
2536
|
+
};
|
|
2537
|
+
function checkTransition(entity, transitions, from, to) {
|
|
2538
|
+
const allowed = transitions[from];
|
|
2539
|
+
if (!allowed) {
|
|
2540
|
+
return {
|
|
2541
|
+
valid: false,
|
|
2542
|
+
reason: `${entity}: unknown current state '${from}'`
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
if (!allowed.includes(to)) {
|
|
2546
|
+
return {
|
|
2547
|
+
valid: false,
|
|
2548
|
+
reason: `${entity}: invalid transition '${from}' \u2192 '${to}'. Allowed: [${allowed.join(", ")}]`
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
return { valid: true };
|
|
2552
|
+
}
|
|
2553
|
+
function validateLoginChallengeTransition(from, to) {
|
|
2554
|
+
return checkTransition(
|
|
2555
|
+
"LoginChallenge",
|
|
2556
|
+
LOGIN_CHALLENGE_TRANSITIONS,
|
|
2557
|
+
from,
|
|
2558
|
+
to
|
|
2559
|
+
);
|
|
2560
|
+
}
|
|
2561
|
+
function validateTickAuthTransition(from, to) {
|
|
2562
|
+
return checkTransition("TickAuthChallenge", TICKAUTH_TRANSITIONS, from, to);
|
|
2563
|
+
}
|
|
2564
|
+
function validateCapsuleTransition(from, to) {
|
|
2565
|
+
return checkTransition("Capsule", CAPSULE_TRANSITIONS, from, to);
|
|
2566
|
+
}
|
|
2567
|
+
function validateSessionTransition(from, to) {
|
|
2568
|
+
return checkTransition("Session", SESSION_TRANSITIONS, from, to);
|
|
2569
|
+
}
|
|
2570
|
+
function validateDeviceTransition(from, to) {
|
|
2571
|
+
return checkTransition("Device", DEVICE_TRANSITIONS, from, to);
|
|
2572
|
+
}
|
|
2573
|
+
function validateTrustLinkTransition(from, to) {
|
|
2574
|
+
return checkTransition("TrustLink", TRUST_LINK_TRANSITIONS, from, to);
|
|
2575
|
+
}
|
|
2576
|
+
function isLoginChallengeTerminal(status) {
|
|
2577
|
+
return [
|
|
2578
|
+
"approved" /* APPROVED */,
|
|
2579
|
+
"rejected" /* REJECTED */,
|
|
2580
|
+
"expired" /* EXPIRED */
|
|
2581
|
+
].includes(status);
|
|
2582
|
+
}
|
|
2583
|
+
function isTickAuthTerminal(status) {
|
|
2584
|
+
return [
|
|
2585
|
+
"fulfilled" /* FULFILLED */,
|
|
2586
|
+
"rejected" /* REJECTED */,
|
|
2587
|
+
"expired" /* EXPIRED */
|
|
2588
|
+
].includes(status);
|
|
2589
|
+
}
|
|
2590
|
+
function isCapsuleTerminal(status) {
|
|
2591
|
+
return [
|
|
2592
|
+
"consumed" /* CONSUMED */,
|
|
2593
|
+
"revoked" /* REVOKED */,
|
|
2594
|
+
"expired" /* EXPIRED */
|
|
2595
|
+
].includes(status);
|
|
2596
|
+
}
|
|
2597
|
+
function isSessionTerminal(status) {
|
|
2598
|
+
return ["expired" /* EXPIRED */, "revoked" /* REVOKED */].includes(status);
|
|
2599
|
+
}
|
|
2600
|
+
function isDeviceTerminal(status) {
|
|
2601
|
+
return status === "revoked" /* REVOKED */;
|
|
2602
|
+
}
|
|
2066
2603
|
export {
|
|
2067
2604
|
ATS1_HDR,
|
|
2068
2605
|
ATS1_SCHEMA,
|
|
@@ -2070,14 +2607,19 @@ export {
|
|
|
2070
2607
|
AXIS_OPCODES,
|
|
2071
2608
|
AXIS_VERSION,
|
|
2072
2609
|
ats1_exports as Ats1Codec,
|
|
2610
|
+
AuthLevel,
|
|
2073
2611
|
AxisFrameZ,
|
|
2074
2612
|
T as AxisPacketTags,
|
|
2075
2613
|
BodyProfile,
|
|
2076
2614
|
CAPABILITIES,
|
|
2615
|
+
CapsuleStatus,
|
|
2077
2616
|
ContractViolationError,
|
|
2078
2617
|
DEFAULT_CONTRACTS,
|
|
2079
2618
|
DEFAULT_TIMEOUT,
|
|
2080
2619
|
Decision,
|
|
2620
|
+
DeviceStatus,
|
|
2621
|
+
DeviceTrustLevel,
|
|
2622
|
+
DeviceType,
|
|
2081
2623
|
ERR_BAD_SIGNATURE,
|
|
2082
2624
|
ERR_CONTRACT_VIOLATION,
|
|
2083
2625
|
ERR_INVALID_PACKET,
|
|
@@ -2096,6 +2638,7 @@ export {
|
|
|
2096
2638
|
Intent,
|
|
2097
2639
|
IntentRouter,
|
|
2098
2640
|
IntentSensitivity,
|
|
2641
|
+
LoginChallengeStatus,
|
|
2099
2642
|
MAX_BODY_LEN,
|
|
2100
2643
|
MAX_FRAME_LEN,
|
|
2101
2644
|
MAX_HDR_LEN,
|
|
@@ -2110,6 +2653,10 @@ export {
|
|
|
2110
2653
|
NCERT_PUB,
|
|
2111
2654
|
NCERT_SCOPE,
|
|
2112
2655
|
NCERT_SIG,
|
|
2656
|
+
NESTFLOW_INTENTS,
|
|
2657
|
+
NESTFLOW_INTENT_SET,
|
|
2658
|
+
NESTFLOW_POLICY_MAP,
|
|
2659
|
+
NestFlowCapsuleType,
|
|
2113
2660
|
PROOF_CAPABILITIES,
|
|
2114
2661
|
PROOF_CAPSULE,
|
|
2115
2662
|
PROOF_JWT,
|
|
@@ -2118,11 +2665,13 @@ export {
|
|
|
2118
2665
|
PROOF_NONE,
|
|
2119
2666
|
PROOF_WITNESS,
|
|
2120
2667
|
ProofType,
|
|
2668
|
+
RiskDecision,
|
|
2121
2669
|
Schema2002_PasskeyLoginOptionsRes,
|
|
2122
2670
|
Schema2011_PasskeyLoginVerifyReq,
|
|
2123
2671
|
Schema2012_PasskeyLoginVerifyRes,
|
|
2124
2672
|
Schema2021_PasskeyRegisterOptionsReq,
|
|
2125
2673
|
SensorDecisions,
|
|
2674
|
+
SessionStatus,
|
|
2126
2675
|
TLV_ACTOR_ID,
|
|
2127
2676
|
TLV_AUD,
|
|
2128
2677
|
TLV_BODY_ARR,
|
|
@@ -2154,6 +2703,9 @@ export {
|
|
|
2154
2703
|
TLV_TRACE_ID,
|
|
2155
2704
|
TLV_TS,
|
|
2156
2705
|
TLV_UPLOAD_ID,
|
|
2706
|
+
TickAuthChallengeStatus,
|
|
2707
|
+
TrustLinkStatus,
|
|
2708
|
+
TrustLinkType,
|
|
2157
2709
|
axis1SigningBytes,
|
|
2158
2710
|
b64urlDecode,
|
|
2159
2711
|
b64urlDecodeString,
|
|
@@ -2167,6 +2719,14 @@ export {
|
|
|
2167
2719
|
canAccessResource,
|
|
2168
2720
|
canonicalJson,
|
|
2169
2721
|
canonicalJsonExcluding,
|
|
2722
|
+
checkBrowserProof,
|
|
2723
|
+
checkCapsule,
|
|
2724
|
+
checkDeviceTrust,
|
|
2725
|
+
checkIntentPolicy,
|
|
2726
|
+
checkLoginChallenge,
|
|
2727
|
+
checkReplayProtection,
|
|
2728
|
+
checkSession,
|
|
2729
|
+
checkTickAuth,
|
|
2170
2730
|
classifyIntent,
|
|
2171
2731
|
computeReceiptHash,
|
|
2172
2732
|
computeSignaturePayload,
|
|
@@ -2183,10 +2743,18 @@ export {
|
|
|
2183
2743
|
encodeTLVs,
|
|
2184
2744
|
encodeVarint,
|
|
2185
2745
|
generateEd25519KeyPair,
|
|
2746
|
+
getRequiredAuthLevel,
|
|
2186
2747
|
getSignTarget,
|
|
2187
2748
|
hasScope,
|
|
2188
2749
|
isAdminOpcode,
|
|
2750
|
+
isCapsuleTerminal,
|
|
2751
|
+
isDeviceTerminal,
|
|
2189
2752
|
isKnownOpcode,
|
|
2753
|
+
isLoginChallengeTerminal,
|
|
2754
|
+
isNestFlowIntent,
|
|
2755
|
+
isSessionTerminal,
|
|
2756
|
+
isTickAuthTerminal,
|
|
2757
|
+
isTimestampValid,
|
|
2190
2758
|
nonce16,
|
|
2191
2759
|
normalizeSensorDecision,
|
|
2192
2760
|
packPasskeyLoginOptionsReq,
|
|
@@ -2196,6 +2764,7 @@ export {
|
|
|
2196
2764
|
packPasskeyRegisterOptionsReq,
|
|
2197
2765
|
parseScope,
|
|
2198
2766
|
resolveTimeout,
|
|
2767
|
+
satisfiesAuthLevel,
|
|
2199
2768
|
sensitivityName,
|
|
2200
2769
|
sha256,
|
|
2201
2770
|
signFrame,
|
|
@@ -2205,6 +2774,13 @@ export {
|
|
|
2205
2774
|
unpackPasskeyLoginVerifyReq,
|
|
2206
2775
|
unpackPasskeyRegisterOptionsReq,
|
|
2207
2776
|
utf8,
|
|
2777
|
+
validateCapsuleTransition,
|
|
2778
|
+
validateDeviceTransition,
|
|
2779
|
+
validateFrameShape,
|
|
2780
|
+
validateLoginChallengeTransition,
|
|
2781
|
+
validateSessionTransition,
|
|
2782
|
+
validateTickAuthTransition,
|
|
2783
|
+
validateTrustLinkTransition,
|
|
2208
2784
|
varintLength,
|
|
2209
2785
|
varintU,
|
|
2210
2786
|
verifyFrameSignature
|