@agentxm/registry-auth 0.28.11 → 0.28.13
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/src/auth-client.d.ts +13 -5
- package/dist/src/auth-client.js +80 -39
- package/dist/src/credential-store.d.ts +39 -2
- package/dist/src/credential-store.js +50 -46
- package/dist/src/device-login.d.ts +20 -8
- package/dist/src/device-login.js +9 -4
- package/dist/src/errors.d.ts +37 -12
- package/dist/src/errors.js +20 -0
- package/dist/src/identity.d.ts +46 -0
- package/dist/src/identity.js +49 -0
- package/dist/src/index.d.ts +12 -2
- package/dist/src/index.js +14 -1
- package/dist/src/internal/environment.d.ts +23 -5
- package/dist/src/internal/environment.js +59 -9
- package/dist/src/live.d.ts +1 -0
- package/dist/src/live.js +1 -0
- package/dist/src/login-presenter.d.ts +55 -0
- package/dist/src/login-presenter.js +22 -0
- package/dist/src/login-suggestion.d.ts +18 -0
- package/dist/src/login-suggestion.js +34 -0
- package/dist/src/login.d.ts +80 -0
- package/dist/src/login.js +155 -0
- package/dist/src/logout.d.ts +35 -0
- package/dist/src/logout.js +37 -0
- package/dist/src/loopback-login.js +2 -1
- package/dist/src/loopback-server.d.ts +3 -1
- package/dist/src/loopback-server.js +51 -7
- package/dist/src/pending-publish-authorization-store.d.ts +33 -0
- package/dist/src/pending-publish-authorization-store.js +90 -0
- package/dist/src/publish-authorization-polling.d.ts +13 -0
- package/dist/src/publish-authorization-polling.js +176 -0
- package/dist/src/publish-authorization.d.ts +4 -1
- package/dist/src/publish-authorization.js +24 -5
- package/dist/src/selected-registry.d.ts +25 -0
- package/dist/src/selected-registry.js +18 -0
- package/dist/src/step-up.d.ts +49 -0
- package/dist/src/step-up.js +174 -0
- package/dist/src/testing.d.ts +1 -0
- package/dist/src/testing.js +1 -0
- package/dist/src/tokens.d.ts +57 -0
- package/dist/src/tokens.js +78 -0
- package/package.json +7 -6
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Granular access-token policy: the expiry grammar and its bounds, the
|
|
3
|
+
* permission payload the Registry accepts, and the human-verification
|
|
4
|
+
* requirement on every token write.
|
|
5
|
+
*
|
|
6
|
+
* @experimental This API is unstable and may change without notice.
|
|
7
|
+
*/
|
|
8
|
+
import * as DateTime from "effect/DateTime";
|
|
9
|
+
import * as Duration from "effect/Duration";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import * as Option from "effect/Option";
|
|
12
|
+
import { AuthClient, } from "./auth-client.js";
|
|
13
|
+
import { CredentialStore } from "./credential-store.js";
|
|
14
|
+
import { RegistryAuthFailed } from "./errors.js";
|
|
15
|
+
import { AuthLoginPresenter } from "./login-presenter.js";
|
|
16
|
+
import { currentToken } from "./identity.js";
|
|
17
|
+
import { runWithStepUp } from "./step-up.js";
|
|
18
|
+
/** A token may live no less than an hour and no more than a year. */
|
|
19
|
+
export const MIN_TOKEN_LIFETIME_SECONDS = 3_600;
|
|
20
|
+
export const MAX_TOKEN_LIFETIME_SECONDS = 31_536_000;
|
|
21
|
+
const invalid = (detail) => new RegistryAuthFailed({ category: "validation", detail });
|
|
22
|
+
/**
|
|
23
|
+
* Read the requested lifetime. Relative forms are exact multiples; an
|
|
24
|
+
* absolute timestamp becomes the distance from now.
|
|
25
|
+
*/
|
|
26
|
+
export const parseExpiresInSeconds = (raw) => {
|
|
27
|
+
const trimmed = raw.trim();
|
|
28
|
+
const relative = /^(\d+)([hdy])$/.exec(trimmed);
|
|
29
|
+
if (relative) {
|
|
30
|
+
const amount = Number(relative[1]);
|
|
31
|
+
const unit = relative[2];
|
|
32
|
+
const multiplier = unit === "h" ? 3_600 : unit === "d" ? 86_400 : 31_536_000;
|
|
33
|
+
return Effect.succeed(amount * multiplier);
|
|
34
|
+
}
|
|
35
|
+
return Option.match(DateTime.make(trimmed), {
|
|
36
|
+
onNone: () => Effect.fail(invalid("Invalid --expires value. Use 7d, 30d, 1y, or an ISO timestamp.")),
|
|
37
|
+
onSome: (expiry) => Effect.map(DateTime.now, (now) => Math.floor(Duration.toSeconds(DateTime.distance(now, expiry)))),
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
/** Enforce the accepted lifetime window. */
|
|
41
|
+
export const validateExpiresInSeconds = (expiresIn) => expiresIn < MIN_TOKEN_LIFETIME_SECONDS || expiresIn > MAX_TOKEN_LIFETIME_SECONDS
|
|
42
|
+
? Effect.fail(invalid("Token expiry must be between 1 hour and 365 days."))
|
|
43
|
+
: Effect.succeed(expiresIn);
|
|
44
|
+
/** Only the authority a caller actually asked for reaches the Registry. */
|
|
45
|
+
export const tokenPermissions = (request) => ({
|
|
46
|
+
...(request.owners.length > 0 ? { owners: request.owners } : {}),
|
|
47
|
+
...(request.extensions.length > 0 ? { extensions: request.extensions } : {}),
|
|
48
|
+
...(Option.isSome(request.permission) ? { permission: request.permission.value } : {}),
|
|
49
|
+
...(Option.isSome(request.orgPermission) ? { org_permission: request.orgPermission.value } : {}),
|
|
50
|
+
...(request.cidr.length > 0 ? { cidr: request.cidr } : {}),
|
|
51
|
+
...(request.bypassMfa ? { bypass_mfa: true } : {}),
|
|
52
|
+
});
|
|
53
|
+
export const createToken = Effect.fn("Tokens.create")(function* (request, registryUrl) {
|
|
54
|
+
const authClient = yield* AuthClient;
|
|
55
|
+
const token = yield* currentToken(registryUrl);
|
|
56
|
+
const expiresIn = yield* parseExpiresInSeconds(request.expires).pipe(Effect.flatMap(validateExpiresInSeconds));
|
|
57
|
+
const created = yield* runWithStepUp((stepUpRequestId) => authClient.createToken(token, { name: request.name, expiresIn, permissions: tokenPermissions(request) }, stepUpRequestId === undefined ? undefined : { stepUpRequestId }), {
|
|
58
|
+
operationLabel: `Create registry token "${request.name}"`,
|
|
59
|
+
waitingLabel: `verification to create registry token "${request.name}"`,
|
|
60
|
+
}, request.verification, registryUrl);
|
|
61
|
+
return { token: created.value, stepUpCompleted: created.stepUpCompleted };
|
|
62
|
+
});
|
|
63
|
+
export const revokeToken = Effect.fn("Tokens.revoke")(function* (tokenId, verification, registryUrl) {
|
|
64
|
+
const authClient = yield* AuthClient;
|
|
65
|
+
const token = yield* currentToken(registryUrl);
|
|
66
|
+
const revoked = yield* runWithStepUp((stepUpRequestId) => authClient.deleteToken(token, tokenId, stepUpRequestId === undefined ? undefined : { stepUpRequestId }), {
|
|
67
|
+
operationLabel: `Revoke registry token ${tokenId}`,
|
|
68
|
+
waitingLabel: `verification to revoke token ${tokenId}`,
|
|
69
|
+
}, verification, registryUrl);
|
|
70
|
+
return { tokenId, stepUpCompleted: revoked.stepUpCompleted };
|
|
71
|
+
});
|
|
72
|
+
export const listTokens = Effect.fn("Tokens.list")(function* (registryUrl) {
|
|
73
|
+
const authClient = yield* AuthClient;
|
|
74
|
+
const presenter = yield* AuthLoginPresenter;
|
|
75
|
+
const token = yield* currentToken(registryUrl);
|
|
76
|
+
return yield* presenter.withProgress({ _tag: "ListingRegistryTokens" }, () => authClient.listTokens(token));
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=tokens.js.map
|
package/package.json
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
"url": "https://github.com/agentxm/axm/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@agentxm/extension-model": "^0.28.
|
|
8
|
-
"@agentxm/registry-client": "^0.28.
|
|
9
|
-
"@agentxm/registry-protocol": "^0.28.
|
|
7
|
+
"@agentxm/extension-model": "^0.28.13",
|
|
8
|
+
"@agentxm/registry-client": "^0.28.13",
|
|
9
|
+
"@agentxm/registry-protocol": "^0.28.13",
|
|
10
10
|
"@napi-rs/keyring": "^1.3.0",
|
|
11
11
|
"effect": "4.0.0-rc.112",
|
|
12
12
|
"proper-lockfile": "^4.1.2"
|
|
13
13
|
},
|
|
14
14
|
"description": "AXM registry-auth feature: login, logout, token, identity inspection, device and loopback flows, and credential lifecycle for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
|
|
15
15
|
"devDependencies": {
|
|
16
|
+
"@agentxm/specification-metadata": "^0.28.13",
|
|
16
17
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
17
18
|
"@effect/vitest": "4.0.0-rc.112",
|
|
18
19
|
"@types/bun": "^1.3.14",
|
|
@@ -55,11 +56,11 @@
|
|
|
55
56
|
"access": "public"
|
|
56
57
|
},
|
|
57
58
|
"repository": {
|
|
58
|
-
"directory": "packages/registry-auth",
|
|
59
|
+
"directory": "packages/supporting/registry-auth",
|
|
59
60
|
"type": "git",
|
|
60
61
|
"url": "https://github.com/agentxm/axm.git"
|
|
61
62
|
},
|
|
62
63
|
"sideEffects": false,
|
|
63
64
|
"type": "module",
|
|
64
|
-
"version": "0.28.
|
|
65
|
-
}
|
|
65
|
+
"version": "0.28.13"
|
|
66
|
+
}
|