@vercel/kms 0.2.1 → 0.3.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @vercel/kms
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @vercel/oidc@3.8.10
8
+
9
+ ## 0.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 53fa954: Add `signJWT`, which returns `{ token, keyId, algorithm, fingerprint }`. Deprecate `signToken` in favor of `signJWT`. `signMessage` now also returns the signing key's `fingerprint`.
14
+
3
15
  ## 0.2.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -9,13 +9,13 @@ automatically via [`@vercel/oidc`](https://www.npmjs.com/package/@vercel/oidc)).
9
9
 
10
10
  ## Usage
11
11
 
12
- ### Signing a token
12
+ ### Signing a JWT
13
13
 
14
14
  ```typescript
15
- import { signToken } from '@vercel/kms';
15
+ import { signJWT } from '@vercel/kms';
16
16
 
17
- // Returns a compact JWT string signed by the issuer.
18
- const token = await signToken({
17
+ // Returns `{ token, keyId, algorithm, fingerprint }`.
18
+ const { token, keyId, algorithm, fingerprint } = await signJWT({
19
19
  issuerId: 'issuer_abc123',
20
20
  claims: { sub: 'user_123', scope: 'read:data' },
21
21
  ttl: 300, // seconds; defaults to 300
@@ -28,8 +28,8 @@ const token = await signToken({
28
28
  import { signMessage } from '@vercel/kms';
29
29
 
30
30
  // `message` is a UTF-8 string or raw bytes (Uint8Array); it is base64-encoded
31
- // internally. Returns `{ signature, keyId, algorithm }`.
32
- const { signature, keyId, algorithm } = await signMessage({
31
+ // internally. Returns `{ signature, keyId, algorithm, fingerprint }`.
32
+ const { signature, keyId, algorithm, fingerprint } = await signMessage({
33
33
  issuerId: 'issuer_abc123',
34
34
  message: 'hello world',
35
35
  });
@@ -41,7 +41,7 @@ By default the OIDC token is fetched via `getVercelOidcToken()`. To supply your
41
41
  own token, pass `token`:
42
42
 
43
43
  ```typescript
44
- const token = await signToken({
44
+ const { token } = await signJWT({
45
45
  issuerId: 'issuer_abc123',
46
46
  token: myOidcToken,
47
47
  });
@@ -49,7 +49,7 @@ const token = await signToken({
49
49
 
50
50
  ## API
51
51
 
52
- ### `signToken(options)`
52
+ ### `signJWT(options)`
53
53
 
54
54
  Signs a JWT for an issuer.
55
55
 
@@ -63,6 +63,16 @@ Signs a JWT for an issuer.
63
63
  - `region?: string` — Region for the regional KMS API host, e.g. `sfo1`, producing `https://api-<region>.vercel.com/v1`. Defaults to the `VERCEL_REGION` environment variable, falling back to `https://api.vercel.com/v1`. Ignored when `baseUrl` is set.
64
64
  - `baseUrl?: string` — Override the API base URL. Takes precedence over `region`.
65
65
 
66
+ Returns `Promise<{ token: string, keyId: string, algorithm: string, fingerprint: string }>` — the compact JWT, plus the key id, algorithm, and public-key fingerprint of the signing key.
67
+
68
+ ### `signToken(options)`
69
+
70
+ Deprecated: use `signJWT` instead.
71
+
72
+ Signs a JWT for an issuer and returns only the compact JWT string.
73
+
74
+ **Options:** same as `signJWT`.
75
+
66
76
  Returns `Promise<string>` — the compact JWT.
67
77
 
68
78
  ### `signMessage(options)`
@@ -77,4 +87,4 @@ Signs a message for an issuer.
77
87
  - `region?: string` — Region for the regional KMS API host, e.g. `sfo1`, producing `https://api-<region>.vercel.com/v1`. Defaults to the `VERCEL_REGION` environment variable, falling back to `https://api.vercel.com/v1`. Ignored when `baseUrl` is set.
78
88
  - `baseUrl?: string` — Override the API base URL. Takes precedence over `region`.
79
89
 
80
- Returns `Promise<{ signature: Uint8Array, keyId: string, algorithm: string }>` — the raw signature bytes, plus the key id and algorithm of the signing key.
90
+ Returns `Promise<{ signature: Uint8Array, keyId: string, algorithm: string, fingerprint: string }>` — the raw signature bytes, plus the key id, algorithm, and public-key fingerprint of the signing key.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { signJWT, type SignJWTOptions, type SignJWTResult } from './sign-jwt';
1
2
  export { signToken, type SignTokenOptions } from './sign-token';
2
3
  export { signMessage, type SignMessageOptions, type SignMessageResult, } from './sign-message';
3
4
  export { VercelKmsError } from './errors';
package/dist/index.js CHANGED
@@ -19,16 +19,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var src_exports = {};
20
20
  __export(src_exports, {
21
21
  VercelKmsError: () => import_errors.VercelKmsError,
22
+ signJWT: () => import_sign_jwt.signJWT,
22
23
  signMessage: () => import_sign_message.signMessage,
23
24
  signToken: () => import_sign_token.signToken
24
25
  });
25
26
  module.exports = __toCommonJS(src_exports);
27
+ var import_sign_jwt = require("./sign-jwt");
26
28
  var import_sign_token = require("./sign-token");
27
29
  var import_sign_message = require("./sign-message");
28
30
  var import_errors = require("./errors");
29
31
  // Annotate the CommonJS export names for ESM import in node:
30
32
  0 && (module.exports = {
31
33
  VercelKmsError,
34
+ signJWT,
32
35
  signMessage,
33
36
  signToken
34
37
  });
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Options for {@link signJWT}.
3
+ */
4
+ export interface SignJWTOptions {
5
+ /** The ID of the issuer whose signing key should sign the token. */
6
+ issuerId: string;
7
+ /** The claims to include in the token. */
8
+ claims?: Record<string, unknown>;
9
+ /** Additional headers to include in the token. */
10
+ headers?: Record<string, unknown>;
11
+ /** The time-to-live for the token, in seconds. Defaults to 300. */
12
+ ttl?: number | null;
13
+ /**
14
+ * An explicit Vercel OIDC token to authenticate with. When omitted, the
15
+ * function's OIDC token is fetched automatically via `@vercel/oidc`.
16
+ */
17
+ token?: string;
18
+ /**
19
+ * Region for the regional KMS API host, e.g. `sfo1`, producing
20
+ * `https://api-<region>.vercel.com/v1`. Defaults to the `VERCEL_REGION`
21
+ * environment variable, falling back to the global `api.vercel.com` host.
22
+ * Ignored when `baseUrl` is provided.
23
+ */
24
+ region?: string;
25
+ /**
26
+ * Override the API base URL. Takes precedence over `region`.
27
+ * @default "https://api-<region>.vercel.com/v1" or "https://api.vercel.com/v1"
28
+ */
29
+ baseUrl?: string;
30
+ }
31
+ /**
32
+ * Result of {@link signJWT}.
33
+ */
34
+ export interface SignJWTResult {
35
+ /** Compact JWT signed by the issuer's active signing key. */
36
+ token: string;
37
+ /** Key id of the signing key. Matches the JWKS `kid`. */
38
+ keyId: string;
39
+ /** Algorithm of the signing key. */
40
+ algorithm: string;
41
+ /**
42
+ * SHA-256 fingerprint of the signing key's public key (`SHA256:<base64>`).
43
+ */
44
+ fingerprint: string;
45
+ }
46
+ /**
47
+ * Signs a JWT for an issuer using its managed signing key and returns the
48
+ * compact JWT plus the `keyId`, `algorithm`, and `fingerprint` of the key that
49
+ * produced it.
50
+ *
51
+ * @throws {import('./errors').VercelKmsError} If the sign request fails.
52
+ */
53
+ export declare function signJWT(options: SignJWTOptions): Promise<SignJWTResult>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var sign_jwt_exports = {};
20
+ __export(sign_jwt_exports, {
21
+ signJWT: () => signJWT
22
+ });
23
+ module.exports = __toCommonJS(sign_jwt_exports);
24
+ var import_request = require("./request");
25
+ var import_resolve_token = require("./resolve-token");
26
+ async function signJWT(options) {
27
+ const { issuerId, claims = {}, headers = {}, ttl = 300, token } = options;
28
+ const baseUrl = (0, import_request.resolveBaseUrl)({
29
+ region: options.region,
30
+ baseUrl: options.baseUrl
31
+ });
32
+ const oidcToken = await (0, import_resolve_token.resolveOidcToken)({ token });
33
+ return (0, import_request.postJson)({
34
+ baseUrl,
35
+ path: `/kms/issuers/${encodeURIComponent(issuerId)}/sign/token`,
36
+ token: oidcToken,
37
+ body: { claims, headers, ttl }
38
+ });
39
+ }
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ signJWT
43
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_oidc = require("@vercel/oidc");
4
+ var import_sign_jwt = require("./sign-jwt");
5
+ var import_errors = require("./errors");
6
+ import_vitest.vi.mock("@vercel/oidc", () => ({
7
+ getVercelOidcToken: import_vitest.vi.fn()
8
+ }));
9
+ const getVercelOidcTokenMock = import_vitest.vi.mocked(import_oidc.getVercelOidcToken);
10
+ const OIDC_TOKEN = "oidc-token";
11
+ const SIGNED_JWT = {
12
+ token: "signed.jwt.token",
13
+ keyId: "key_a",
14
+ algorithm: "ES256",
15
+ fingerprint: "SHA256:test"
16
+ };
17
+ function fetchReturning(body, init) {
18
+ return async () => new Response(JSON.stringify(body), { status: 200, ...init });
19
+ }
20
+ (0, import_vitest.describe)("signJWT", () => {
21
+ (0, import_vitest.beforeEach)(() => {
22
+ import_vitest.vi.restoreAllMocks();
23
+ getVercelOidcTokenMock.mockReset();
24
+ delete process.env.VERCEL_REGION;
25
+ });
26
+ (0, import_vitest.test)("signs a JWT and returns the token plus signing key metadata", async () => {
27
+ getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
28
+ const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning(SIGNED_JWT));
29
+ const result = await (0, import_sign_jwt.signJWT)({
30
+ issuerId: "issuer_a",
31
+ claims: { sub: "user" }
32
+ });
33
+ (0, import_vitest.expect)(result).toEqual(SIGNED_JWT);
34
+ (0, import_vitest.expect)(getVercelOidcTokenMock).toHaveBeenCalledWith();
35
+ (0, import_vitest.expect)(fetchMock).toHaveBeenCalledTimes(1);
36
+ const [url, init] = fetchMock.mock.calls[0];
37
+ (0, import_vitest.expect)(url.toString()).toBe(
38
+ "https://api.vercel.com/v1/kms/issuers/issuer_a/sign/token"
39
+ );
40
+ (0, import_vitest.expect)(init?.method).toBe("POST");
41
+ (0, import_vitest.expect)((init?.headers).authorization).toBe(
42
+ `Bearer ${OIDC_TOKEN}`
43
+ );
44
+ (0, import_vitest.expect)(JSON.parse(init?.body)).toEqual({
45
+ claims: { sub: "user" },
46
+ headers: {},
47
+ ttl: 300
48
+ });
49
+ });
50
+ (0, import_vitest.test)("targets the regional host when a region is provided", async () => {
51
+ getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
52
+ const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning(SIGNED_JWT));
53
+ await (0, import_sign_jwt.signJWT)({ issuerId: "issuer_region", region: "sfo1" });
54
+ const [url] = fetchMock.mock.calls[0];
55
+ (0, import_vitest.expect)(url.toString()).toBe(
56
+ "https://api-sfo1.vercel.com/v1/kms/issuers/issuer_region/sign/token"
57
+ );
58
+ });
59
+ (0, import_vitest.test)("uses an explicit token without fetching an OIDC token", async () => {
60
+ const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning(SIGNED_JWT));
61
+ await (0, import_sign_jwt.signJWT)({ issuerId: "issuer_explicit", token: "my-token" });
62
+ (0, import_vitest.expect)(getVercelOidcTokenMock).not.toHaveBeenCalled();
63
+ const [, init] = fetchMock.mock.calls[0];
64
+ (0, import_vitest.expect)((init?.headers).authorization).toBe(
65
+ "Bearer my-token"
66
+ );
67
+ });
68
+ (0, import_vitest.test)("throws a VercelKmsError mapping the API error envelope", async () => {
69
+ getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
70
+ import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(
71
+ fetchReturning(
72
+ { error: { code: "issuer_not_found", message: "nope", issuerId: "x" } },
73
+ { status: 404, statusText: "Not Found" }
74
+ )
75
+ );
76
+ await (0, import_vitest.expect)((0, import_sign_jwt.signJWT)({ issuerId: "x" })).rejects.toMatchObject({
77
+ name: "VercelKmsError",
78
+ status: 404,
79
+ code: "issuer_not_found",
80
+ message: "nope",
81
+ metadata: { issuerId: "x" }
82
+ });
83
+ await (0, import_vitest.expect)((0, import_sign_jwt.signJWT)({ issuerId: "x" })).rejects.toBeInstanceOf(
84
+ import_errors.VercelKmsError
85
+ );
86
+ });
87
+ });
@@ -38,12 +38,17 @@ export interface SignMessageResult {
38
38
  keyId: string;
39
39
  /** Algorithm of the signing key. */
40
40
  algorithm: string;
41
+ /**
42
+ * SHA-256 fingerprint of the signing key's public key (`SHA256:<base64>`).
43
+ */
44
+ fingerprint: string;
41
45
  }
42
46
  /**
43
47
  * Signs a message for an issuer using its managed signing key and returns the
44
- * raw signature over the message bytes, plus the `keyId` and `algorithm` of
45
- * the key that produced it. The message may be provided as raw bytes
46
- * (`Uint8Array`) or a UTF-8 `string`; it is base64-encoded before being sent.
48
+ * raw signature over the message bytes, plus the `keyId`, `algorithm`, and
49
+ * `fingerprint` of the key that produced it. The message may be provided as
50
+ * raw bytes (`Uint8Array`) or a UTF-8 `string`; it is base64-encoded before
51
+ * being sent.
47
52
  *
48
53
  * @throws {import('./errors').VercelKmsError} If the sign request fails.
49
54
  */
@@ -30,13 +30,13 @@ async function signMessage(options) {
30
30
  baseUrl: options.baseUrl
31
31
  });
32
32
  const oidcToken = await (0, import_resolve_token.resolveOidcToken)({ token });
33
- const { signature, keyId, algorithm } = await (0, import_request.postJson)({
33
+ const { signature, keyId, algorithm, fingerprint } = await (0, import_request.postJson)({
34
34
  baseUrl,
35
35
  path: `/kms/issuers/${encodeURIComponent(issuerId)}/sign/message`,
36
36
  token: oidcToken,
37
37
  body: { message: toBase64(message) }
38
38
  });
39
- return { signature: fromBase64(signature), keyId, algorithm };
39
+ return { signature: fromBase64(signature), keyId, algorithm, fingerprint };
40
40
  }
41
41
  function toBase64(message) {
42
42
  return (typeof message === "string" ? Buffer.from(message, "utf-8") : Buffer.from(message)).toString("base64");
@@ -22,7 +22,8 @@ const SIGNATURE_BYTES = new Uint8Array([
22
22
  const SIGNED_MESSAGE = {
23
23
  signature: SIGNATURE_B64,
24
24
  keyId: "key_a",
25
- algorithm: "EdDSA"
25
+ algorithm: "EdDSA",
26
+ fingerprint: "SHA256:test"
26
27
  };
27
28
  function fetchReturning(body, init) {
28
29
  return async () => new Response(JSON.stringify(body), { status: 200, ...init });
@@ -43,7 +44,8 @@ function fetchReturning(body, init) {
43
44
  (0, import_vitest.expect)(result).toEqual({
44
45
  signature: SIGNATURE_BYTES,
45
46
  keyId: "key_a",
46
- algorithm: "EdDSA"
47
+ algorithm: "EdDSA",
48
+ fingerprint: "SHA256:test"
47
49
  });
48
50
  (0, import_vitest.expect)(getVercelOidcTokenMock).toHaveBeenCalledWith();
49
51
  const [url, init] = fetchMock.mock.calls[0];
@@ -1,37 +1,17 @@
1
+ import { type SignJWTOptions } from './sign-jwt';
1
2
  /**
2
3
  * Options for {@link signToken}.
4
+ *
5
+ * @deprecated Use {@link SignJWTOptions} instead.
3
6
  */
4
- export interface SignTokenOptions {
5
- /** The ID of the issuer whose signing key should sign the token. */
6
- issuerId: string;
7
- /** The claims to include in the token. */
8
- claims?: Record<string, unknown>;
9
- /** Additional headers to include in the token. */
10
- headers?: Record<string, unknown>;
11
- /** The time-to-live for the token, in seconds. Defaults to 300. */
12
- ttl?: number | null;
13
- /**
14
- * An explicit Vercel OIDC token to authenticate with. When omitted, the
15
- * function's OIDC token is fetched automatically via `@vercel/oidc`.
16
- */
17
- token?: string;
18
- /**
19
- * Region for the regional KMS API host, e.g. `sfo1`, producing
20
- * `https://api-<region>.vercel.com/v1`. Defaults to the `VERCEL_REGION`
21
- * environment variable, falling back to the global `api.vercel.com` host.
22
- * Ignored when `baseUrl` is provided.
23
- */
24
- region?: string;
25
- /**
26
- * Override the API base URL. Takes precedence over `region`.
27
- * @default "https://api-<region>.vercel.com/v1" or "https://api.vercel.com/v1"
28
- */
29
- baseUrl?: string;
30
- }
7
+ export type SignTokenOptions = SignJWTOptions;
31
8
  /**
32
9
  * Signs a JWT for an issuer using its managed signing key and returns the
33
10
  * compact JWT string.
34
11
  *
12
+ * @deprecated Use {@link signJWT} instead, which returns the signed JWT plus
13
+ * the signing key's `keyId`, `algorithm`, and `fingerprint`.
14
+ *
35
15
  * @throws {import('./errors').VercelKmsError} If the sign request fails.
36
16
  */
37
17
  export declare function signToken(options: SignTokenOptions): Promise<string>;
@@ -21,22 +21,10 @@ __export(sign_token_exports, {
21
21
  signToken: () => signToken
22
22
  });
23
23
  module.exports = __toCommonJS(sign_token_exports);
24
- var import_request = require("./request");
25
- var import_resolve_token = require("./resolve-token");
24
+ var import_sign_jwt = require("./sign-jwt");
26
25
  async function signToken(options) {
27
- const { issuerId, claims = {}, headers = {}, ttl = 300, token } = options;
28
- const baseUrl = (0, import_request.resolveBaseUrl)({
29
- region: options.region,
30
- baseUrl: options.baseUrl
31
- });
32
- const oidcToken = await (0, import_resolve_token.resolveOidcToken)({ token });
33
- const { token: signedToken } = await (0, import_request.postJson)({
34
- baseUrl,
35
- path: `/kms/issuers/${encodeURIComponent(issuerId)}/sign/token`,
36
- token: oidcToken,
37
- body: { claims, headers, ttl }
38
- });
39
- return signedToken;
26
+ const { token } = await (0, import_sign_jwt.signJWT)(options);
27
+ return token;
40
28
  }
41
29
  // Annotate the CommonJS export names for ESM import in node:
42
30
  0 && (module.exports = {
@@ -2,13 +2,17 @@
2
2
  var import_vitest = require("vitest");
3
3
  var import_oidc = require("@vercel/oidc");
4
4
  var import_sign_token = require("./sign-token");
5
- var import_errors = require("./errors");
6
5
  import_vitest.vi.mock("@vercel/oidc", () => ({
7
6
  getVercelOidcToken: import_vitest.vi.fn()
8
7
  }));
9
8
  const getVercelOidcTokenMock = import_vitest.vi.mocked(import_oidc.getVercelOidcToken);
10
9
  const OIDC_TOKEN = "oidc-token";
11
- const SIGNED_TOKEN = "signed.jwt.token";
10
+ const SIGNED_JWT = {
11
+ token: "signed.jwt.token",
12
+ keyId: "key_a",
13
+ algorithm: "ES256",
14
+ fingerprint: "SHA256:test"
15
+ };
12
16
  function fetchReturning(body, init) {
13
17
  return async () => new Response(JSON.stringify(body), { status: 200, ...init });
14
18
  }
@@ -18,65 +22,16 @@ function fetchReturning(body, init) {
18
22
  getVercelOidcTokenMock.mockReset();
19
23
  delete process.env.VERCEL_REGION;
20
24
  });
21
- (0, import_vitest.test)("signs a token and returns the JWT string", async () => {
22
- getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
23
- const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning({ token: SIGNED_TOKEN }));
24
- const result = await (0, import_sign_token.signToken)({
25
- issuerId: "issuer_a",
26
- claims: { sub: "user" }
27
- });
28
- (0, import_vitest.expect)(result).toBe(SIGNED_TOKEN);
29
- (0, import_vitest.expect)(getVercelOidcTokenMock).toHaveBeenCalledWith();
30
- (0, import_vitest.expect)(fetchMock).toHaveBeenCalledTimes(1);
31
- const [url, init] = fetchMock.mock.calls[0];
32
- (0, import_vitest.expect)(url.toString()).toBe(
33
- "https://api.vercel.com/v1/kms/issuers/issuer_a/sign/token"
34
- );
35
- (0, import_vitest.expect)(init?.method).toBe("POST");
36
- (0, import_vitest.expect)((init?.headers).authorization).toBe(
37
- `Bearer ${OIDC_TOKEN}`
38
- );
39
- (0, import_vitest.expect)(JSON.parse(init?.body)).toEqual({
40
- claims: { sub: "user" },
41
- headers: {},
42
- ttl: 300
43
- });
44
- });
45
- (0, import_vitest.test)("targets the regional host when a region is provided", async () => {
46
- getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
47
- const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning({ token: SIGNED_TOKEN }));
48
- await (0, import_sign_token.signToken)({ issuerId: "issuer_region", region: "sfo1" });
49
- const [url] = fetchMock.mock.calls[0];
50
- (0, import_vitest.expect)(url.toString()).toBe(
51
- "https://api-sfo1.vercel.com/v1/kms/issuers/issuer_region/sign/token"
52
- );
53
- });
54
- (0, import_vitest.test)("uses an explicit token without fetching an OIDC token", async () => {
55
- const fetchMock = import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(fetchReturning({ token: SIGNED_TOKEN }));
56
- await (0, import_sign_token.signToken)({ issuerId: "issuer_explicit", token: "my-token" });
57
- (0, import_vitest.expect)(getVercelOidcTokenMock).not.toHaveBeenCalled();
58
- const [, init] = fetchMock.mock.calls[0];
59
- (0, import_vitest.expect)((init?.headers).authorization).toBe(
60
- "Bearer my-token"
61
- );
62
- });
63
- (0, import_vitest.test)("throws a VercelKmsError mapping the API error envelope", async () => {
25
+ (0, import_vitest.test)("returns the compact JWT string from the signJWT response", async () => {
64
26
  getVercelOidcTokenMock.mockResolvedValue(OIDC_TOKEN);
65
27
  import_vitest.vi.spyOn(globalThis, "fetch").mockImplementation(
66
- fetchReturning(
67
- { error: { code: "issuer_not_found", message: "nope", issuerId: "x" } },
68
- { status: 404, statusText: "Not Found" }
69
- )
70
- );
71
- await (0, import_vitest.expect)((0, import_sign_token.signToken)({ issuerId: "x" })).rejects.toMatchObject({
72
- name: "VercelKmsError",
73
- status: 404,
74
- code: "issuer_not_found",
75
- message: "nope",
76
- metadata: { issuerId: "x" }
77
- });
78
- await (0, import_vitest.expect)((0, import_sign_token.signToken)({ issuerId: "x" })).rejects.toBeInstanceOf(
79
- import_errors.VercelKmsError
28
+ fetchReturning(SIGNED_JWT)
80
29
  );
30
+ await (0, import_vitest.expect)(
31
+ (0, import_sign_token.signToken)({
32
+ issuerId: "issuer_a",
33
+ claims: { sub: "user" }
34
+ })
35
+ ).resolves.toBe(SIGNED_JWT.token);
81
36
  });
82
37
  });
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.2.1";
1
+ export declare const version = "0.3.1";
package/dist/version.js CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  version: () => version
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const version = "0.2.1";
24
+ const version = "0.3.1";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  version
package/docs/README.md CHANGED
@@ -10,11 +10,17 @@
10
10
 
11
11
  ## Interfaces
12
12
 
13
+ - [SignJWTOptions](interfaces/SignJWTOptions.md)
14
+ - [SignJWTResult](interfaces/SignJWTResult.md)
13
15
  - [SignMessageOptions](interfaces/SignMessageOptions.md)
14
16
  - [SignMessageResult](interfaces/SignMessageResult.md)
15
- - [SignTokenOptions](interfaces/SignTokenOptions.md)
17
+
18
+ ## Type Aliases
19
+
20
+ - [~~SignTokenOptions~~](type-aliases/SignTokenOptions.md)
16
21
 
17
22
  ## Functions
18
23
 
24
+ - [signJWT](functions/signJWT.md)
19
25
  - [signMessage](functions/signMessage.md)
20
- - [signToken](functions/signToken.md)
26
+ - [~~signToken~~](functions/signToken.md)
@@ -0,0 +1,27 @@
1
+ [**@vercel/kms**](../README.md)
2
+
3
+ ---
4
+
5
+ # Function: signJWT()
6
+
7
+ > **signJWT**(`options`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<[`SignJWTResult`](../interfaces/SignJWTResult.md)\>
8
+
9
+ Defined in: [packages/kms/src/sign-jwt.ts:58](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L58)
10
+
11
+ Signs a JWT for an issuer using its managed signing key and returns the
12
+ compact JWT plus the `keyId`, `algorithm`, and `fingerprint` of the key that
13
+ produced it.
14
+
15
+ ## Parameters
16
+
17
+ ### options
18
+
19
+ [`SignJWTOptions`](../interfaces/SignJWTOptions.md)
20
+
21
+ ## Returns
22
+
23
+ [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<[`SignJWTResult`](../interfaces/SignJWTResult.md)\>
24
+
25
+ ## Throws
26
+
27
+ If the sign request fails.
@@ -6,12 +6,13 @@
6
6
 
7
7
  > **signMessage**(`options`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<[`SignMessageResult`](../interfaces/SignMessageResult.md)\>
8
8
 
9
- Defined in: [packages/kms/src/sign-message.ts:55](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-message.ts#L55)
9
+ Defined in: [packages/kms/src/sign-message.ts:60](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-message.ts#L60)
10
10
 
11
11
  Signs a message for an issuer using its managed signing key and returns the
12
- raw signature over the message bytes, plus the `keyId` and `algorithm` of
13
- the key that produced it. The message may be provided as raw bytes
14
- (`Uint8Array`) or a UTF-8 `string`; it is base64-encoded before being sent.
12
+ raw signature over the message bytes, plus the `keyId`, `algorithm`, and
13
+ `fingerprint` of the key that produced it. The message may be provided as
14
+ raw bytes (`Uint8Array`) or a UTF-8 `string`; it is base64-encoded before
15
+ being sent.
15
16
 
16
17
  ## Parameters
17
18
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  ---
4
4
 
5
- # Function: signToken()
5
+ # ~~Function: signToken()~~
6
6
 
7
7
  > **signToken**(`options`): [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<`string`\>
8
8
 
9
- Defined in: [packages/kms/src/sign-token.ts:41](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L41)
9
+ Defined in: [packages/kms/src/sign-token.ts:19](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L19)
10
10
 
11
11
  Signs a JWT for an issuer using its managed signing key and returns the
12
12
  compact JWT string.
@@ -15,12 +15,17 @@ compact JWT string.
15
15
 
16
16
  ### options
17
17
 
18
- [`SignTokenOptions`](../interfaces/SignTokenOptions.md)
18
+ [`SignJWTOptions`](../interfaces/SignJWTOptions.md)
19
19
 
20
20
  ## Returns
21
21
 
22
22
  [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)\<`string`\>
23
23
 
24
+ ## Deprecated
25
+
26
+ Use [signJWT](signJWT.md) instead, which returns the signed JWT plus
27
+ the signing key's `keyId`, `algorithm`, and `fingerprint`.
28
+
24
29
  ## Throws
25
30
 
26
31
  If the sign request fails.
@@ -2,11 +2,11 @@
2
2
 
3
3
  ---
4
4
 
5
- # Interface: SignTokenOptions
5
+ # Interface: SignJWTOptions
6
6
 
7
- Defined in: [packages/kms/src/sign-token.ts:7](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L7)
7
+ Defined in: [packages/kms/src/sign-jwt.ts:7](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L7)
8
8
 
9
- Options for [signToken](../functions/signToken.md).
9
+ Options for [signJWT](../functions/signJWT.md).
10
10
 
11
11
  ## Properties
12
12
 
@@ -14,7 +14,7 @@ Options for [signToken](../functions/signToken.md).
14
14
 
15
15
  > `optional` **baseUrl?**: `string`
16
16
 
17
- Defined in: [packages/kms/src/sign-token.ts:32](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L32)
17
+ Defined in: [packages/kms/src/sign-jwt.ts:32](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L32)
18
18
 
19
19
  Override the API base URL. Takes precedence over `region`.
20
20
 
@@ -30,7 +30,7 @@ Override the API base URL. Takes precedence over `region`.
30
30
 
31
31
  > `optional` **claims?**: [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)\<`string`, `unknown`\>
32
32
 
33
- Defined in: [packages/kms/src/sign-token.ts:11](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L11)
33
+ Defined in: [packages/kms/src/sign-jwt.ts:11](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L11)
34
34
 
35
35
  The claims to include in the token.
36
36
 
@@ -40,7 +40,7 @@ The claims to include in the token.
40
40
 
41
41
  > `optional` **headers?**: [`Record`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type)\<`string`, `unknown`\>
42
42
 
43
- Defined in: [packages/kms/src/sign-token.ts:13](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L13)
43
+ Defined in: [packages/kms/src/sign-jwt.ts:13](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L13)
44
44
 
45
45
  Additional headers to include in the token.
46
46
 
@@ -50,7 +50,7 @@ Additional headers to include in the token.
50
50
 
51
51
  > **issuerId**: `string`
52
52
 
53
- Defined in: [packages/kms/src/sign-token.ts:9](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L9)
53
+ Defined in: [packages/kms/src/sign-jwt.ts:9](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L9)
54
54
 
55
55
  The ID of the issuer whose signing key should sign the token.
56
56
 
@@ -60,7 +60,7 @@ The ID of the issuer whose signing key should sign the token.
60
60
 
61
61
  > `optional` **region?**: `string`
62
62
 
63
- Defined in: [packages/kms/src/sign-token.ts:27](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L27)
63
+ Defined in: [packages/kms/src/sign-jwt.ts:27](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L27)
64
64
 
65
65
  Region for the regional KMS API host, e.g. `sfo1`, producing
66
66
  `https://api-<region>.vercel.com/v1`. Defaults to the `VERCEL_REGION`
@@ -73,7 +73,7 @@ Ignored when `baseUrl` is provided.
73
73
 
74
74
  > `optional` **token?**: `string`
75
75
 
76
- Defined in: [packages/kms/src/sign-token.ts:20](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L20)
76
+ Defined in: [packages/kms/src/sign-jwt.ts:20](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L20)
77
77
 
78
78
  An explicit Vercel OIDC token to authenticate with. When omitted, the
79
79
  function's OIDC token is fetched automatically via `@vercel/oidc`.
@@ -84,6 +84,6 @@ function's OIDC token is fetched automatically via `@vercel/oidc`.
84
84
 
85
85
  > `optional` **ttl?**: `number` \| `null`
86
86
 
87
- Defined in: [packages/kms/src/sign-token.ts:15](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L15)
87
+ Defined in: [packages/kms/src/sign-jwt.ts:15](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L15)
88
88
 
89
89
  The time-to-live for the token, in seconds. Defaults to 300.
@@ -0,0 +1,49 @@
1
+ [**@vercel/kms**](../README.md)
2
+
3
+ ---
4
+
5
+ # Interface: SignJWTResult
6
+
7
+ Defined in: [packages/kms/src/sign-jwt.ts:38](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L38)
8
+
9
+ Result of [signJWT](../functions/signJWT.md).
10
+
11
+ ## Properties
12
+
13
+ ### algorithm
14
+
15
+ > **algorithm**: `string`
16
+
17
+ Defined in: [packages/kms/src/sign-jwt.ts:44](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L44)
18
+
19
+ Algorithm of the signing key.
20
+
21
+ ---
22
+
23
+ ### fingerprint
24
+
25
+ > **fingerprint**: `string`
26
+
27
+ Defined in: [packages/kms/src/sign-jwt.ts:48](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L48)
28
+
29
+ SHA-256 fingerprint of the signing key's public key (`SHA256:<base64>`).
30
+
31
+ ---
32
+
33
+ ### keyId
34
+
35
+ > **keyId**: `string`
36
+
37
+ Defined in: [packages/kms/src/sign-jwt.ts:42](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L42)
38
+
39
+ Key id of the signing key. Matches the JWKS `kid`.
40
+
41
+ ---
42
+
43
+ ### token
44
+
45
+ > **token**: `string`
46
+
47
+ Defined in: [packages/kms/src/sign-jwt.ts:40](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-jwt.ts#L40)
48
+
49
+ Compact JWT signed by the issuer's active signing key.
@@ -20,6 +20,16 @@ Algorithm of the signing key.
20
20
 
21
21
  ---
22
22
 
23
+ ### fingerprint
24
+
25
+ > **fingerprint**: `string`
26
+
27
+ Defined in: [packages/kms/src/sign-message.ts:48](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-message.ts#L48)
28
+
29
+ SHA-256 fingerprint of the signing key's public key (`SHA256:<base64>`).
30
+
31
+ ---
32
+
23
33
  ### keyId
24
34
 
25
35
  > **keyId**: `string`
@@ -0,0 +1,15 @@
1
+ [**@vercel/kms**](../README.md)
2
+
3
+ ---
4
+
5
+ # ~~Type Alias: SignTokenOptions~~
6
+
7
+ > **SignTokenOptions** = [`SignJWTOptions`](../interfaces/SignJWTOptions.md)
8
+
9
+ Defined in: [packages/kms/src/sign-token.ts:8](https://github.com/vercel/vercel-internal/blob/main/packages/kms/src/sign-token.ts#L8)
10
+
11
+ Options for [signToken](../functions/signToken.md).
12
+
13
+ ## Deprecated
14
+
15
+ Use [SignJWTOptions](../interfaces/SignJWTOptions.md) instead.
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "require": "./dist/index.js"
15
15
  }
16
16
  },
17
- "version": "0.2.1",
17
+ "version": "0.3.1",
18
18
  "repository": {
19
19
  "directory": "packages/kms",
20
20
  "type": "git",
@@ -24,7 +24,7 @@
24
24
  "url": "https://github.com/vercel/vercel/issues"
25
25
  },
26
26
  "dependencies": {
27
- "@vercel/oidc": "3.8.9"
27
+ "@vercel/oidc": "3.8.10"
28
28
  },
29
29
  "devDependencies": {
30
30
  "prettier": "3.8.3",