UNPKG

@eqxjs/azure-manage-identity

Version:

For get Azure keyvault secret

144 lines 6.58 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyJWTToken = verifyJWTToken; exports.verifyJWTTokenBySecret = verifyJWTTokenBySecret; exports.signJWTToken = signJWTToken; const keyvault_keys_1 = require("@azure/keyvault-keys"); const jwt = __importStar(require("jsonwebtoken")); const confidential_mgnt_1 = require("../confidential.mgnt"); const secret_get_1 = require("../secret/secret.get"); const base64url_1 = __importDefault(require("base64url")); const util_1 = require("util"); const node_crypto_1 = require("node:crypto"); const node_buffer_1 = require("node:buffer"); /** * Converts a JWK (JSON Web Key) object to a PEM-encoded public key string * using Node.js built-in crypto — no external library required. * * @param jwk - The JWK object to convert * @returns PEM-encoded SPKI public key string */ function jwkToPem(jwk) { const key = (0, node_crypto_1.createPublicKey)({ key: jwk, format: 'jwk' }); return key.export({ type: 'spki', format: 'pem' }); } /** * Verifies a JWT token using an Azure Key Vault key via cryptographic verification. * The token's signature is verified using the SHA-256 digest of the header and payload. * * @param keyURL - The URL of the Azure Key Vault instance * @param keyName - The name of the key to use for verification * @param algorithm - The signing algorithm identifier (e.g. `'ES256'`) * @param jwtToken - The JWT token string in `header.payload.signature` format * @returns A promise resolving to a {@link VerifyResult} indicating success or failure * @throws {Error} When the JWT token is not in a valid 3-part format */ async function verifyJWTToken(keyURL, keyName, algorithm, jwtToken) { const credential = new confidential_mgnt_1.MyClientAssertionCredential(); const keysClient = new keyvault_keys_1.KeyClient(keyURL, credential); const vaultKey = await keysClient.getKey(keyName); const cryptographyClient = new keyvault_keys_1.CryptographyClient(vaultKey, credential); const jwtArray = jwtToken.split('.'); if (jwtArray.length != 3) { throw new Error(`Invalid JWT: ${jwtToken}`); } const signature = base64url_1.default.toBuffer(jwtArray[2]); const data = (0, util_1.format)('%s.%s', jwtArray[0], jwtArray[1]); const hash = (0, node_crypto_1.createHash)('sha256'); const digest = hash.update(data).digest(); return cryptographyClient.verify(algorithm, digest, signature); } /** * Verifies a JWT token against a JWK set stored as a secret in Azure Key Vault. * Iterates over all keys in the JWK set; returns `true` if any key validates the token. * * @param keyURL - The URL of the Azure Key Vault instance * @param secretName - The name of the secret containing the JWK set as a JSON string * @param jwtToken - The JWT token string to verify * @returns A promise resolving to a {@link VerifyResult} with `result: true` on success * @throws {Error} When all keys fail verification, or the secret is not a valid JWK set */ async function verifyJWTTokenBySecret(keyURL, secretName, jwtToken) { const secret = await (0, secret_get_1.getSecret)(keyURL, secretName); const returnCode = { result: false, keyID: '' }; returnCode.result = false; const publicKey = JSON.parse(secret.value ?? ''); let lastError = ''; if (publicKey.keys && Array.isArray(publicKey.keys)) { for (const i in publicKey.keys) { try { const pem = jwkToPem(publicKey.keys[i]); jwt.verify(jwtToken, pem, { algorithms: ['RS256'] }); returnCode.result = true; } catch (error) { lastError = `Verify token error ${error}`; continue; } } if (!returnCode.result) { throw new Error(lastError); } } else { throw new Error(`Invalid public key: ${secret.value}`); } return returnCode; } /** * Signs a payload using an Azure Key Vault key and returns a base64url-encoded signature. * The payload is hashed with SHA-256 before signing. * * @param keyURL - The URL of the Azure Key Vault instance * @param keyName - The name of the key to use for signing * @param algorithm - The signing algorithm identifier (e.g. `'ES256'`) * @param payload - The string payload to sign * @returns A promise resolving to the base64url-encoded signature string */ async function signJWTToken(keyURL, keyName, algorithm, payload) { const credential = new confidential_mgnt_1.MyClientAssertionCredential(); const keysClient = new keyvault_keys_1.KeyClient(keyURL, credential); const vaultKey = await keysClient.getKey(keyName); const cryptographyClient = new keyvault_keys_1.CryptographyClient(vaultKey, credential); const hash = (0, node_crypto_1.createHash)('sha256'); const digest = hash.update(payload).digest(); const result = await cryptographyClient.sign(algorithm, digest); return base64url_1.default.encode(node_buffer_1.Buffer.from(result.result)); } //# sourceMappingURL=jwt.verify.js.map