Skip to content

guides

Intended Documentation

Connector SDK

Build custom connectors with the Intended Connector SDK to extend authorization enforcement to downstream systems, data stores, and third-party services.

Connector SDK#

The Connector SDK is production-ready and enforces fail-closed decision-token validation before adapter execution.

The Intended Connector SDK lets you build custom connectors that extend Intended authorization enforcement to downstream systems -- databases, object stores, SaaS APIs, message queues, or any service that should respect Intended decision tokens before executing operations.

A connector acts as an enforcement bridge: it receives a verified decision from the Intended runtime, translates it into the access-control primitives of the target system, and reports the enforcement outcome back to Intended for audit.

Architecture Overview#

┌──────────────┐     ┌───────────────────┐     ┌──────────────────┐
│  Intended       │────▶│  Your Connector   │────▶│  Downstream      │
│  Runtime      │     │  (Connector SDK)  │     │  System          │
│              │◀────│                   │◀────│  (DB, API, etc.) │
└──────────────┘     └───────────────────┘     └──────────────────┘
     decision           enforce + translate        execute or deny

Installation#

Info

Use pinned versions in production environments to keep connector behavior deterministic across releases.

bash
npm install @intended/connector-sdk

Connector Interface Contract#

Every connector must implement the IntendedConnector interface. This contract defines the methods the Intended runtime calls during the connector lifecycle.

typescript
import {
  IntendedConnector,
  ConnectorConfig,
  EnforcementContext,
  EnforcementResult,
  HealthStatus,
} from "@intended/connector-sdk";

export class PostgresConnector implements IntendedConnector {
  readonly id = "connector:postgres-prod";
  readonly version = "0.1.0";
  readonly targetSystem = "postgresql";

  async initialize(config: ConnectorConfig): Promise<void> {
    // Set up connection pool, validate credentials
    this.pool = await createPool(config.connectionString);
  }

  async enforce(context: EnforcementContext): Promise<EnforcementResult> {
    // Translate Intended decision into Postgres access control
    const { decision, intent, resource, actor } = context;

    if (decision !== "allow") {
      return {
        enforced: true,
        action: "denied",
        reason: `Decision was ${decision}`,
      };
    }

    // Apply row-level security context for this actor
    await this.pool.query("SET LOCAL meritt.actor = $1", [actor]);
    await this.pool.query("SET LOCAL meritt.intent = $1", [intent]);

    return {
      enforced: true,
      action: "allowed",
      metadata: { resource, actor },
    };
  }

  async healthCheck(): Promise<HealthStatus> {
    try {
      await this.pool.query("SELECT 1");
      return { healthy: true };
    } catch (error) {
      return { healthy: false, error: error.message };
    }
  }

  async shutdown(): Promise<void> {
    await this.pool.end();
  }
}

Lifecycle Hooks#

The Intended runtime manages connectors through a defined lifecycle. Each hook is called at a specific phase.

initialize

Called once when the connector is first loaded. Use this to set up connections, validate configuration, and allocate resources. If initialization fails, the connector is marked unhealthy and not used for enforcement.

enforce

Called on every enforcement request routed to this connector. Receives the verified decision context and must return an EnforcementResult indicating whether enforcement succeeded.

healthCheck

Called periodically by the runtime (default: every 30 seconds). Return a HealthStatus indicating whether the connector and its downstream system are operational.

shutdown

Called when the connector is being deregistered or the runtime is shutting down. Clean up connections, flush buffers, and release resources.

Registration#

Info

Connector registration is stable and backed by versioned capability manifests.

Register your connector with the Intended runtime by submitting a connector manifest:

POST/admin/connectors/configureRequires auth

Register a new connector with the Intended runtime.

idstring*Unique connector identifier (e.g., 'connector:postgres-prod')
versionstring*Semantic version of the connector
target_systemstring*Type of downstream system (e.g., 'postgresql', 's3', 'salesforce')
endpointstring*URL where the connector is reachable by the runtime
intentsstring[]*List of intents this connector handles

Registration Request#

bash
curl -X POST https://api.intended.so/admin/connectors/configure \
  -H "Authorization: Bearer $Intended_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "connector:postgres-prod",
    "version": "0.1.0",
    "target_system": "postgresql",
    "endpoint": "https://connectors.internal/postgres-prod",
    "intents": ["query-data", "summarize-document", "generate-report"]
  }'

Registration Response#

json
{
  "id": "connector:postgres-prod",
  "status": "registered",
  "health": "pending",
  "registered_at": "2026-03-08T10:00:00Z"
}

Error Handling#

Connectors must handle errors gracefully and report them through the EnforcementResult:

typescript
async enforce(context: EnforcementContext): Promise<EnforcementResult> {
  try {
    // Attempt enforcement on downstream system
    await this.applyAccessControl(context);
    return { enforced: true, action: "allowed" };
  } catch (error) {
    // Report failure -- the runtime will mark this enforcement as failed
    return {
      enforced: false,
      action: "error",
      reason: `Downstream error: ${error.message}`,
      retryable: isTransient(error),
    };
  }
}
Error ScenarioenforcedactionRuntime Behavior
Decision allowed, downstream appliedtrueallowedAudit logged as success
Decision denied, downstream blockedtruedeniedAudit logged as denied
Downstream unreachablefalseerrorRetry if retryable: true; escalate otherwise
Connector bug or crashfalseerrorRuntime marks connector unhealthy after threshold

Info

Retry behavior and circuit-breaker thresholds are versioned and deterministic: 3 retries with exponential backoff, circuit opens after 5 consecutive failures.

Testing Your Connector#

Use the SDK test harness to validate your connector locally before registration:

typescript
import { ConnectorTestHarness } from "@intended/connector-sdk/testing";

const harness = new ConnectorTestHarness(new PostgresConnector());

// Simulate the full lifecycle
await harness.testInitialize({ connectionString: "postgresql://..." });
await harness.testHealthCheck(); // expects { healthy: true }
await harness.testEnforce({
  decision: "allow",
  intent: "query-data",
  resource: "table:users",
  actor: "agent:analytics-v1",
}); // expects { enforced: true, action: "allowed" }
await harness.testShutdown();

Troubleshooting#

ProblemCauseRemediation
Connector stuck in pending healthinitialize failed silentlyCheck logs for initialization errors; verify credentials
enforce returns error consistentlyDownstream system unreachableVerify network connectivity; check health endpoint
Runtime does not route to connectorIntent mismatchEnsure registered intents match the intents from evaluation
Connector deregistered unexpectedlyHealth check failures exceeded thresholdReview healthCheck implementation; increase timeout if needed

Next Steps#