Skip to main content

Run HAIEC from Any Coding Agent

Every coding agent reaches the same HAIEC Assurance pipeline — MCP-capable agents through the remote MCP server, everything else through the Assurance API. Give the agent the configuration values and a short instruction block; it triggers the same remote Assurance run a server application would.

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

1. Where the instructions live

Each tool has its own instruction file. The content is the same — pick the location your tool reads. Never put the API key in the instruction file.

ToolInstruction fileGuide
Cursor.cursor/rules/haiec-assurance.mdcGuide →
Claude CodeCLAUDE.md (repo root)Guide →
DevinAGENTS.md (repo root)Guide →
Windsurf.windsurf/rules/ or AGENTS.mdUse this page
GitHub Copilot.github/copilot-instructions.mdUse this page
Any other agent / scriptAGENTS.md (repo root)Use this page

2. Preferred — HAIEC MCP server (MCP-capable agents)

If your agent supports remote MCP servers (Cursor, Claude Code, Devin, or any Streamable-HTTP MCP client), point it at https://www.haiec.com/api/mcp with Authorization: Bearer <HAIEC_API_KEY> — no local process, no stdio. Agents without MCP support use the REST instructions below.

// Generic MCP client config — remote Streamable HTTP endpoint
{
  "mcpServers": {
    "haiec": {
      "url": "https://www.haiec.com/api/mcp",
      "headers": { "Authorization": "Bearer <HAIEC_API_KEY>" }
    }
  }
}

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

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.

3. 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.
  • Never prefix the key with NEXT_PUBLIC_. For production, use your platform's secret manager.

4. Portable instructions — AGENTS.md

AGENTS.md is the portable default — most coding agents read it. Paste this section into your repository root file:

## 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

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\"
    } }
  }"

Server-side TypeScript 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

Machine-readable discovery: /.well-known/haiec-capabilities.json and /openapi/assurance-v1.yaml.

What the agent should do

  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.