UNPKG

@cerbos/embedded

Version:

Client library for interacting with embedded Cerbos policy decision points generated by Cerbos Hub from server-side Node.js and browser-based applications

119 lines 4.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DecisionLogger = void 0; const ulid_1 = require("ulid"); const core_1 = require("@cerbos/core"); class DecisionLogger { log; userAgent; ulid; constructor(log, userAgent) { this.log = log; this.userAgent = userAgent; this.ulid = (0, ulid_1.monotonicFactory)(); } async logCheckResources(request, auxData, headers, response, bundleMetadata, error) { const callId = this.ulid(); const inputs = request.resources.map(({ resource, actions }) => ({ ...(0, core_1._checkInputFromProtobuf)({ $typeName: "cerbos.engine.v1.CheckInput", requestId: request.requestId, principal: request.principal, resource, actions, }), auxData, })); const outputs = []; const effectivePolicies = {}; if (response) { response.cerbosCallId = callId; for (const result of response.results) { (0, core_1._requireField)("CheckResourcesResponse.ResultEntry.resource", result.resource); (0, core_1._requireField)("CheckResourcesResponse.ResultEntry.meta", result.meta); const actions = {}; for (const [action, effect] of Object.entries(result.actions)) { const meta = result.meta.actions[action]; actions[action] = { $typeName: "cerbos.engine.v1.CheckOutput.ActionEffect", effect, policy: meta?.matchedPolicy ?? "", scope: meta?.matchedScope ?? "", }; if (meta?.matchedPolicy && !effectivePolicies[meta.matchedPolicy]) { for (const ancestor of ancestors(meta.matchedPolicy)) { effectivePolicies[ancestor] ??= { commit_hash: bundleMetadata.commit, ...bundleMetadata.sourceAttributes[`cerbos.${ancestor}`], }; } } } outputs.push((0, core_1._checkOutputFromProtobuf)({ $typeName: "cerbos.engine.v1.CheckOutput", requestId: response.requestId, resourceId: result.resource.id, actions, outputs: result.outputs, effectiveDerivedRoles: result.meta.effectiveDerivedRoles, validationErrors: result.validationErrors, })); } } await this.log({ callId, method: { name: "CheckResources", inputs, outputs, error: errorMessage(error), }, timestamp: new Date(), metadata: metadata(headers), oversized: false, auditTrail: { effectivePolicies, }, peer: { address: "", authInfo: "", forwardedFor: "", userAgent: this.userAgent, }, policySource: { kind: "embeddedPDP", url: bundleMetadata.url ?? "", commit: bundleMetadata.commit, builtAt: bundleMetadata.builtAt, }, }); } } exports.DecisionLogger = DecisionLogger; function errorMessage(error) { if (error === undefined) { return undefined; } if (error instanceof Error) { return error.message; } return "Unknown error"; } function metadata(headers) { const metadata = {}; for (const [name, value] of headers) { (metadata[name] ??= []).push(value); } return metadata; } const scopedPolicyIdPattern = /\.v[^/]+(?<separator>\/)[^/]+$/d; function* ancestors(policyId) { const match = scopedPolicyIdPattern.exec(policyId); if (match) { for (let end = match.indices.groups.separator[0]; end > 0; end = policyId.indexOf(".", end + 1)) { yield policyId.substring(0, end); } } yield policyId; } //# sourceMappingURL=logger.js.map