browsec/trustlab/plugins/policy-overlay-plugin.js

62 lines
1.7 KiB
JavaScript

export function createPolicyOverlayPlugin(overlay) {
const evidenceByConnection = new Map();
return {
manifest: {
manifestVersion: 1,
trustApiVersion: "0.1",
id: "org.browsec.local-policy-overlay",
name: "Browsec local trust policy",
version: "0.1.0",
supportedModes: ["decision-authority"],
capabilities: {},
},
hooks: {
collectEvidence({ facts }) {
const rule = overlay.match(facts);
if (!rule) return undefined;
evidenceByConnection.set(facts.connectionId, rule.id);
return {
entries: [
{
kind: "evidence",
code: "local-policy-rule-matched",
message: `${rule.sourcePluginName} stored a matching ${rule.trusted ? "trusted" : "not-trusted"} rule.`,
data: { ruleId: rule.id, trusted: rule.trusted },
},
],
};
},
onBeforeTlsAccept(context) {
return decideFromOverlay(context);
},
async onTlsFailure(context) {
return decideFromOverlay(context);
},
},
};
function decideFromOverlay({ facts, journal }) {
const expectedRuleId = evidenceByConnection.get(facts.connectionId);
const rule = overlay.take(facts);
evidenceByConnection.delete(facts.connectionId);
if (!rule || rule.id !== expectedRuleId) return undefined;
return {
trusted: rule.trusted,
scope: rule.scope,
lifetime: rule.lifetime,
overriddenErrors: rule.overriddenErrors,
reasonEntryIds: journal.entries
.filter(
(entry) =>
entry.pluginId === "org.browsec.local-policy-overlay" &&
entry.data?.ruleId === rule.id,
)
.map((entry) => entry.id),
};
}
}