Skip to main content

Run HAIEC from Cursor

Cursor does not need special HAIEC endpoints. It calls the same Assurance API used by every other client. Your IDE sends the HAIEC API key and the configured system/source identifiers — GitHub repository credentials stay server-side between HAIEC and the GitHub App.

Prerequisite: the repository is already connected to a HAIEC AI System through the GitHub App and the Source Asset shows CONNECTED + VERIFIED. See the Connected GitHub guide first.

1. Environment — server-side only

# .env.local — SERVER_SIDE_ONLY. Must be gitignored.
# Never prefix the API key with NEXT_PUBLIC_.
# Use the "IDE / Agent Full Assurance" purpose for the complete IDE
# workflow (setup + evidence + receipts); "Assurance Agent" remains a
# read/run/evidence-only key.
HAIEC_BASE_URL=https://www.haiec.com
HAIEC_API_KEY=haiec_live_xxx
HAIEC_AI_SYSTEM_ID=SYSTEM_ID
HAIEC_SOURCE_ASSET_ID=VERIFIED_SOURCE_ID
  • .env.local must be gitignored. It is a convenience store, not an automatic shell export — Cursor's agent reads the configuration you provide or values you export in the terminal.
  • Never prefix the key with NEXT_PUBLIC_. Never paste the key into a chat message. If the agent reports it is missing, export it yourself.
  • For production applications, put the key in the platform's secret manager instead.

2. Preferred — HAIEC MCP server

Cursor supports remote MCP servers. With HAIEC MCP configured, the agent calls HAIEC tools directly — haiec_run_assurance, haiec_get_agent_audit, and the rest — instead of hand-writing HTTP calls. Same API key, same tenant scope.

// .cursor/mcp.json — or ~/.cursor/mcp.json for all projects
{
  "mcpServers": {
    "haiec": {
      "url": "https://www.haiec.com/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:HAIEC_API_KEY}"
      }
    }
  }
}

If MCP is configured, prefer the MCP tools (haiec_run_assurance, haiec_get_agent_audit, haiec_list_systems, ...). If only HAIEC_API_KEY is set, use the Assurance REST API v1 below — both surfaces reach the same canonical pipeline with the same tenant and scope enforcement.

HAIEC Assurance MCP (https://www.haiec.com/api/mcp — Streamable HTTP, stateless; protocol 2026-07-28 modern + stateless compatibility for 2025-era clients; Bearer HAIEC_API_KEY, not OAuth). Full IDE journey: PREFLIGHT → SETUP → RUN → POLL → UNDERSTAND → RESOLVE → RE-EVALUATE → VERIFY OUTPUTS. 1) haiec_preflight — the IDE control plane. Returns tenant identity (org name/ID, key name, scopes — never key material), AI System targets with exact IDs and selectionRequired (multiple systems → ASK the user, never pick by display name), setup checks, and actions marked canExecuteViaIde/browserRequired/confirmationRequired/ recommendedTool. 2) SETUP (ide-full key required — perform only approved actions): - No system → haiec_create_ai_system (userConfirmed). - No GitHub App → haiec_github_preflight gives the installation URL; the user installs in the browser, then you poll to resume. - haiec_list_github_repositories → haiec_bind_github_source (userConfirmed) → verification through the trusted path. - No repo access → haiec_submit_local_scan + haiec_run_assurance attachedScanId (canonical ci-attached). - haiec_list_connectors tells you what is LIVE vs Enterprise POC. - haiec_setup_telemetry (userConfirmed) → binder + OTLP endpoints + collector config template; verify via haiec_get_telemetry_status. - Manual asset registration (haiec_register_asset) is always REGISTERED + NOT_VERIFIED — never claim verification you did not earn. 3) haiec_run_assurance — requires a caller-generated idempotencyKey (UUID per intended run; same key+payload replays, key+changed-payload conflicts). 4) haiec_get_run until evaluation.evaluationId appears. 5) haiec_get_summary. 6) haiec_get_agent_audit — the primary explanation surface. Its resolutionGroups field groups open verificationItems into deterministic resolution groups (verificationNeeded verbatim, affected question/path IDs, resolutionOwner, canIdeHelp, recommendedTool, approvalRequired, browserActionRequired, missingInputs, rerunWillNotResolve). Use it to reduce many open items to a few evidence needs — it never invents requirements or changes any status. 7) haiec_get_report only when deeper analysis is needed. Runtime testing (optional — same canonical owner as the dashboard): - haiec_runtime_preflight — read-only safety plan for an endpoint + categories (executable vs HELD, missing acknowledgements). - haiec_run_runtime_test — executes ONLY when the user explicitly confirms: userConfirmedRuntimeTest: true plus authorizationAcknowledged: true. Non-demo endpoints also need responseOnlyTargetAcknowledged: true. staticScanId binds the test to an AI System for later attach. - haiec_list_runtime_tests / haiec_get_runtime_test — discover and poll; attachableOnly + aiSystemId classify what can feed an Evaluation. To fold qualified runtime evidence into Assurance, attach the runtime test to a NEW run: haiec_run_assurance with attachRuntimeTestId (canonical engines.runtime executionMode "attach"). Policy/intent evidence: haiec_get/submit_capability_declaration and haiec_get/submit_operating_envelope (DRAFT only — approval stays dashboard-owned) after user confirmation; draft constraints must be presented to the user as a proposal, never invented from code. Outputs: haiec_issue_assurance_package (userConfirmed) issues the PRIVATE Decision Receipt; haiec_get_package reads state/integrity; haiec_publish_package (userConfirmedPublish — distinct flag) publishes publicly; haiec_revoke_package (userConfirmed + reason) revokes. Completed Evaluations are visible in the dashboard even with NO_RECEIPT. Never translate UNKNOWN / NOT_ASSESSED / EVIDENCE_NEEDED into PASS or FAIL. Evidence upload (haiec_ingest_structured / haiec_ingest_logs) requires userConfirmedUpload: true reflecting real user approval. Telemetry, evidence, and runtime are optional — never blockers for static Assurance.

## Guided Assurance (how to act on open items) Your AI guides the assurance process. HAIEC determines the evidence and Assurance state. After an Evaluation: 1. Say what HAIEC ESTABLISHED first — established facts need no action. 2. Use haiec_get_agent_audit and its resolutionGroups field to group remaining open items by evidence need (e.g. "11 open questions reduce to 3 evidence needs"). Ask ONE useful question at a time, not one per row. 3. Use verificationNeeded verbatim for the resolution step. Do not re-run the same scan expecting progress when the gap needs a different evidence family (provider/IAM export, runtime witness, policy authorization, deployment continuity). 4. Offer to help obtain or evaluate evidence — uploads always require explicit user confirmation, then a NEW Evaluation before claiming a delta. 5. UNKNOWN means the question remains open — explain what is already known, why current evidence cannot answer the rest, and what would resolve it. UNKNOWN != PASS and UNKNOWN != FAIL.

## When the user asks to "run HAIEC" — decision sequence 1. FULL ASSURANCE — HAIEC MCP or API key is configured and reachable: use the normal Assurance workflow (haiec_preflight → haiec_run_assurance → poll → summary → agent audit). 2. SETUP REQUIRED — HAIEC MCP is connected but haiec_preflight reports setup incomplete: explain the exact missing steps from preflight verbatim. If a local repository is available, you may also offer a Quick Check (below) — never in place of completing setup. 3. NO HAIEC CONNECTION — no API key or MCP configured, local repository available: say exactly — "Full HAIEC Assurance is not connected for this repository. I can still run HAIEC's independent local developer-security tools for a preliminary source-security review. These results are not a HAIEC Assurance Evaluation and will not appear in the HAIEC Assurance dashboard." Offer, only with the user's approval before installing or running: - AI AppSec (npx -y ai-appsec) — deterministic static source-security analysis for AI/agent code (requires Semgrep installed separately). - MCP Tenant Isolation (npx -y mcp-tenant-isolation mcp) — only when the repository builds MCP servers or tools. ## Presenting Quick Check results Inspect the repository deeply and propose fixes, but keep three kinds of statements clearly separate: - DETERMINISTIC PACKAGE FINDING — exactly what the scanner reported (rule, file, line). Quote it; never rewrite it as a HAIEC finding. - AI REPOSITORY INTERPRETATION — your reading in this codebase's context (reachability, exploitability, affected paths). - AI RECOMMENDATION — likely remediation and what to verify. Lead with the most important findings first, name the affected files, state the package's limitations, and close with what a full HAIEC Assurance Evaluation could additionally answer (capability and action-path analysis, authority/policy evidence, runtime evidence, Guided Assurance, Agent Audit, Reports, Passport). After the check, say: "These were independent HAIEC developer-security checks performed locally. They do not create a HAIEC Assurance Evaluation and are not stored in your HAIEC Assurance dashboard. Full HAIEC Assurance adds broader capability and action-path analysis, authority and policy evidence, runtime evidence, Guided Assurance, Agent Audit, Reports and Passport." Truth locks: - AI_APPSEC_RESULT != HAIEC_ASSURANCE_EVALUATION - MCP_TENANT_ISOLATION_RESULT != HAIEC_ASSURANCE_EVALUATION - FREE_LOCAL_CHECK != FULL_HAIEC_ASSURANCE - LOCAL_PACKAGE_RESULT != HAIEC_DASHBOARD_EVIDENCE

3. Option A — Cursor Project Rule (REST)

Cursor supports project rules under .cursor/rules/. Save the following as .cursor/rules/haiec-assurance.mdc — it contains no credentials.

---
description: HAIEC Assurance — remote evaluation for this repository
globs:
alwaysApply: false
---

# HAIEC Assurance

This repository is connected to a HAIEC AI System through the HAIEC
GitHub App. HAIEC is an external assurance service — do not modify
application code to run it.

## Credentials and configuration

- Read HAIEC_BASE_URL, HAIEC_API_KEY, HAIEC_AI_SYSTEM_ID, and
  HAIEC_SOURCE_ASSET_ID from the environment or from the project's
  non-public .env.local if the developer has placed them there.
- NEVER print, display, commit, or write HAIEC_API_KEY to any file,
  response, log, or commit. If it is missing, ask the user to export it.
- NEVER send a GitHub token, GITHUB_TOKEN, X-GitHub-Token, or any
  repository credential to HAIEC. The GitHub App handles repository access.
- NEVER send an organizationId; the organization comes from the API key.

## When the user asks to run HAIEC Assurance

1. Confirm all four configuration values are present; if
   HAIEC_SOURCE_ASSET_ID is missing, list evaluation sources via
   GET {base}/api/v1/systems/{systemId}/evaluation-sources and use only a
   VERIFIED source — never guess a repository URL.
2. POST {base}/api/v1/assurance/runs with header
   "Authorization: Bearer $HAIEC_API_KEY" and a fresh Idempotency-Key:
   { "aiSystemId": "...",
     "engines": { "static": { "enabled": true,
       "executionMode": "api", "sourceAssetId": "..." } } }
3. Poll GET {base}/api/v1/assurance/runs/{runId} every 15-30s. Stop on a
   terminal failure and report the structured failure object.
4. When evaluation.evaluationId appears, GET links.summary, then
   links.agentAudit, and report: run ID, evaluation ID, disposition, what
   HAIEC established, what it did not establish, evidence gaps,
   verification items, limitations, and links.report / links.passport /
   links.dashboard.
5. NEVER manufacture PASS. If evidence is unavailable or partial, say so.
6. Explaining findings is fine; remediation requires a separate user
   instruction.

## Reading a HAIEC result (canonical order)

1. POST Assurance Run → 2. poll the run → 3. GET links.summary →
4. GET links.agentAudit → 5. GET links.report ONLY when deeper technical
   detail is required (the agent-audit answers most questions).

The agent-audit is a deterministic projection of the exact persisted
evaluation. Use it verbatim:

- narrative.established — what HAIEC actually established
- narrative.unestablished — material facts it did NOT establish
- narrative.notAssessed — areas explicitly not assessed
- narrative.evidenceGaps — the exact missing evidence
- narrative.limitations — bounded limitations of the result
- authoritySummary — authority-plane state
- verificationItems[] — per item: whatHaiecFound, whatItEstablishes,
  whatHaiecDidNotEstablish, whyItMatters, verificationNeeded,
  affectedQuestionIds, affectedPathIds, evidenceRefs, boundary

verificationNeeded is the authoritative evidence request. Explain it in
plain language if helpful, but never invent evidence requirements beyond
it and never present the paraphrase as HAIEC truth.

Never translate:
- NOT_ASSESSED → FAIL
- UNKNOWN → FAIL
- MISSING_EVIDENCE → VULNERABILITY
- NO_RUNTIME_WITNESS → ACTION_DID_NOT_OCCUR
- EVIDENCE_INGESTED → GAP_CLOSED

## Submitting evidence (only when the user explicitly asks)

Never upload evidence automatically. When the user asks to provide or
connect evidence for HAIEC:

1. Show the user what will be sent (category, source, record count) and
   get explicit confirmation.
2. List eligible binders: GET {base}/api/v1/evidence/binders. Choose an
   active binder matching the source — if none fits, say "this evidence
   source needs to be connected in HAIEC first" and point the user to the
   dashboard. Never invent a binderId.
3. Submit through the canonical intake routes with the same Bearer key
   (requires the evidence:ingest scope):
   - POST /api/ingest/structured  { binderId, format, payload } — JSON/JSONL/CSV events
   - POST /api/ingest/log         { binderId, payload } — raw log lines
   - POST /api/otlp/v1/traces|metrics|logs?binderId=... — OTLP signals
4. Return the ingestion receipt (ingestionId / producerRunId, accepted,
   rejected, failures) verbatim.
5. NEVER claim a gap closed. A receipt means EVIDENCE_INGESTED — only a
   NEW Assurance Evaluation can establish whether anything changed.

To evaluate the new evidence, attach the receipt's producerRunId to a NEW
run: POST /api/v1/assurance/runs with
externalEvidenceAttachments: [{ "producerId": "structured-ingress",
"producerRunId": "<receipt.producerRunId>" }]. Then poll the new run, GET
its agent-audit, and compare old evaluation vs new evaluation facts side
by side — label that comparison as your own analysis of two HAIEC outputs,
not a new HAIEC disposition. Historical evaluations never change.

Never upload: .env files, credentials, secrets, private keys, tokens,
repository archives, or unrelated files. If the key returns 403 on intake,
it lacks evidence:ingest — ask the user to create an Assurance Agent key.

4. Option B — AGENTS.md

Prefer a portable agent file? Cursor also reads AGENTS.mdat the repository root. Either mechanism works — do not need both.

## HAIEC Assurance (external service)

HAIEC evaluates this repository through its Assurance API. Do not modify
source code to run it.

- Env: HAIEC_BASE_URL, HAIEC_API_KEY, HAIEC_AI_SYSTEM_ID, HAIEC_SOURCE_ASSET_ID
  (server-side only — never print or commit the key; never NEXT_PUBLIC_*)
- Run: POST /api/v1/assurance/runs { aiSystemId, engines.static =
  { enabled, executionMode: "api", sourceAssetId } } + Idempotency-Key
- Poll GET /api/v1/assurance/runs/{runId} every 15–30s; report run ID,
  evaluation ID, disposition, findings/limitations, report + dashboard links.
- Explain results from links.summary → links.agentAudit → links.report
  (in that order). Use narrative.established / unestablished / notAssessed /
  evidenceGaps and verificationItems[].verificationNeeded verbatim.
- Never send GitHub tokens or organizationId. Never fabricate PASS on
  missing/partial evidence. NOT_ASSESSED != FAIL. UNKNOWN != FAIL.
- Evidence submission only on explicit user request via configured binders
  (GET /api/v1/evidence/binders; evidence:ingest scope). A receipt means
  EVIDENCE_INGESTED — never claim a gap closed before a new Evaluation.
- Capability manifest: /.well-known/haiec-capabilities.json

5. The underlying API calls

The rule above performs exactly this — nothing Cursor-specific:

curl -X POST "$HAIEC_BASE_URL/api/v1/assurance/runs" \
  -H "Authorization: Bearer $HAIEC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen || date +%s)" \
  -d "{
    \"aiSystemId\": \"$HAIEC_AI_SYSTEM_ID\",
    \"engines\": { \"static\": {
        \"enabled\": true,
        \"executionMode\": \"api\",
        \"sourceAssetId\": \"$HAIEC_SOURCE_ASSET_ID\"
    } }
  }"

A server-side TypeScript equivalent using native fetch:

// server-side only — never in browser/bundled code
const res = await fetch(`${process.env.HAIEC_BASE_URL}/api/v1/assurance/runs`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.HAIEC_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    aiSystemId: process.env.HAIEC_AI_SYSTEM_ID,
    engines: { static: { enabled: true,
      executionMode: 'api',
      sourceAssetId: process.env.HAIEC_SOURCE_ASSET_ID } },
  }),
})
const run = await res.json() // { runId, links.self, ... } — poll until evaluation.evaluationId

What the agent should do

After setup, “Run HAIEC Assurance on this application” should make the agent:

  1. Read the four configuration identifiers from environment or non-public config.
  2. Verify a VERIFIED Source Asset is configured — never a raw repository URL.
  3. POST the Assurance Run with an idempotency key.
  4. Poll the run at a reasonable interval; stop on terminal failure.
  5. GET links.summary, then links.agentAudit — fetch links.report only when deeper technical detail is needed.
  6. Report run ID, evaluation ID, disposition, what HAIEC established, what it did not establish, evidence gaps, verification items, and limitations — plus report and dashboard links.
  7. When the user asks "what is missing" or "what would close this gap", answer from verificationItems[].verificationNeeded and narrative.evidenceGaps — never invent evidence requirements.
  8. Submit evidence only on an explicit user request, only to a configured binder, and never claim a gap closed until a NEW evaluation establishes it.
  • Never display, commit, or log HAIEC_API_KEY.
  • Never send a GitHub token or organizationId to HAIEC.
  • Never present missing or partial evidence as PASS.
  • Never translate NOT_ASSESSED or UNKNOWN into FAIL, or missing evidence into a vulnerability.
  • Never upload .env files, credentials, secrets, private keys, or repository archives as evidence.
  • An ingestion receipt means EVIDENCE_INGESTED — never EVIDENCE_EVALUATED or GAP_CLOSED.
  • Never set userConfirmedRuntimeTest or authorizationAcknowledged on your own — they must reflect actual user statements.
  • Running a scan must not change application code; remediation is a separate instruction.