Skip to content

Quickstart

This guide authorizes one action: an agent is about to export customer records to an external destination. The export runs only when Vulnify returns ALLOW.

These samples match @vulnify/sdk 0.3.0 and vulnify 0.4.0. On Node.js, check() and getEvent() require finalDecision. To keep policies in git, use the CLI. The Python CLI is pip install "vulnify[cli]".

  1. Create an API key

    Sign in at app.vulnify.io. Owners and admins create keys under API keys. Copy the key when it is shown. Vulnify stores only a hash, so it cannot be shown again.

    Use a TEST key while you are trying the API. Test events are sandbox events: they stay out of dashboards and usage. Details are on API keys.

  2. Install an SDK

    The Node.js SDK needs Node.js 18 or newer. The Python SDK needs Python 3.9 or newer and uses only the standard library.

    Terminal window
    npm install @vulnify/sdk
  3. Ask before the export

    Set VULNIFY_API_KEY. Both SDKs call https://api.vulnify.io when you omit the base URL. On Node.js, pass baseUrl: process.env.VULNIFY_BASE_URL to point at another host. The constructor does not read that variable itself. On Python, VULNIFY_BASE_URL is used when base_url is omitted, and an explicit base_url wins.

    import { Vulnify } from '@vulnify/sdk';
    const apiKey = process.env.VULNIFY_API_KEY;
    if (!apiKey) {
    throw new Error('Set VULNIFY_API_KEY');
    }
    const vulnify = new Vulnify({
    apiKey,
    baseUrl: process.env.VULNIFY_BASE_URL,
    });
    /** Replace the body with the real export. It runs only after ALLOW. */
    async function exportCustomerRecords(): Promise<void> {
    console.log('exporting customer records to the external destination');
    }
    const decision = await vulnify.check({
    agent: 'SalesBot',
    action: 'EXPORT_DATA',
    resource: 'Customer Database',
    destination: 'EXTERNAL_EMAIL',
    recordsAffected: 12000,
    });
    const outcome = decision.finalDecision;
    if (outcome === 'ALLOW') {
    await exportCustomerRecords();
    } else if (outcome === 'REVIEW') {
    const reasons = decision.reasons.join('; ') || 'no reason given';
    const score = decision.riskScore == null ? 'unknown' : String(decision.riskScore);
    throw new Error(
    `A human must approve this export before it runs (event ${decision.id ?? 'none'}, score ${score}). ${reasons}`,
    );
    } else if (decision.degraded) {
    throw new Error(`Vulnify could not be reached. The export was not run. ${decision.reasons.join('; ')}`);
    } else {
    throw new Error(`Export blocked. The export was not run. ${decision.reasons.join('; ')}`);
    }

SalesBot and Customer Database must be the agent and resource names registered in your organization. An unknown agent or resource, a rejected payload, an invalid API key, or a body over 200 KB (HTTP 413) raises an error. Those errors are not turned into ALLOW when fail-open is set. Run the export only when finalDecision is ALLOW. Right after check(), that matches decision unless a review is already resolved. A later read of the same event can keep decision as REVIEW while finalDecision becomes ALLOW. See Decisions.

The same check, with guard(), is shorter. guard() runs your function only for ALLOW and throws for REVIEW and BLOCK. See Node.js and Python.

Decision, anomaly, and test notifications arrive as signed HTTP POSTs. The event list, headers, and signature check are on Webhooks.