Skip to content

Security: MMVFIRM/openagentforce

Security

SECURITY.md

Security model — Salesforce-native release

Deployment status

Version 0.5 is a hardened, Salesforce-capable product candidate with Heisenberg, an optional governed LLM interface. It has passed local security, product, and stateful Salesforce contract tests, but it has not undergone an external penetration test or a live customer-org security review.

Salesforce trust boundary

Salesforce remains the system of record and permission authority. OpenAgentForce authenticates as a dedicated Salesforce integration user and can observe or mutate only the objects and fields exposed to that user. Object and field permissions discovered through Salesforce describe metadata are enforced again before OpenAgentForce dispatches supported record writes.

Use a different Salesforce integration user, External Client App, OpenAgentForce connector, and credential set for each sandbox and production org. Do not connect OpenAgentForce with a human administrator account.

Authentication and credential storage

Supported Salesforce authentication modes are:

  • JWT bearer for unattended server-to-server operation;
  • refresh token;
  • client credentials where enabled by the Salesforce app configuration;
  • a pre-issued access token for bounded testing.

JWT private keys, client secrets, refresh tokens, and access tokens are encrypted in OpenAgentForce's secret store. Connector read APIs never return secret values. Platform startup fails closed unless OpenAgentForce's own encryption configuration is valid.

A production deployment should place Salesforce credentials in an external secret manager and inject them at runtime. The built-in encrypted store is useful for a single-node deployment but is not a substitute for managed key rotation, hardware-backed keys, or organization-wide secret governance.

Metadata and field-level enforcement

OpenAgentForce retrieves describe global and per-sObject describe metadata using the connected integration user. The schema catalog checks:

  • object create, update, delete, and query capabilities;
  • field create/update visibility;
  • required fields;
  • picklist values;
  • external-ID designation;
  • primitive type and length constraints where exposed by describe.

Salesforce can still reject a request because of sharing, validation rules, duplicate rules, Flow, Apex, record locks, transaction state, or other org-specific logic. OpenAgentForce treats the Salesforce response as authoritative.

Optional LLM trust boundary

LLM providers are disabled until an administrator stores and tests a provider configuration. API keys are encrypted and are not returned by provider APIs. The model receives the user prompt, bounded conversation history, tool schemas, and the results of tools it calls; those results can contain Salesforce customer data. Provider selection must match the organization's data-handling requirements.

The LLM never receives Salesforce credentials and cannot submit arbitrary SOQL or arbitrary Salesforce REST paths. It can use only the bounded tools exposed by OpenAgentForce. Structured Salesforce queries are validated against live describe metadata. Mutations are previews unless the caller explicitly enables execution, supplies an idempotency key, and passes environment authorization. Provider-level object, operation, and delegated-agent allowlists can narrow the tool surface further.

OpenAI and Anthropic adapters use their native tool-call continuation protocols. Azure, Ollama, and other OpenAI-compatible providers use Chat Completions-style tool calls. Remote OpenAI-compatible endpoints require HTTPS; plaintext HTTP is allowed only on loopback for a local model server. Administrators should treat any custom compatible endpoint as a trusted data processor.

Salesforce record text is untrusted data. A model can encounter prompt-injection-like instructions inside fields, attachments, or knowledge content. The system prompt directs the model to treat tool results as evidence rather than authority, but deterministic tool validation—not the prompt—is the security boundary. Production evaluation must include adversarial content tests.

Salesforce write integrity

Business writes—including Salesforce CRUD, upsert, Composite operations submitted through the action gateway, and Bulk ingest phases exposed by the Salesforce REST surface—use OpenAgentForce's action state machine:

prepared -> dispatched -> succeeded | failed | outcome_unknown

Every execution requires a client-supplied idempotency key scoped by tenant, environment, and connector. The action row is persisted before dispatch. A transport failure or timeout is outcome_unknown, because the remote mutation might have committed.

Unknown outcomes must be reconciled using a Salesforce record ID, job ID, transaction reference, subsequent read, or other provider evidence. Compensation is a separate audited action and does not become definitive unless the compensation itself is known to have succeeded.

Bulk API jobs are multi-phase remote operations. Job creation, CSV upload, and close are separate idempotent OpenAgentForce executions. Job status and result retrieval are read operations.

Production execution gate

Production execution requires:

  1. an API key permitted to access the production environment;
  2. production_execute=true on that key;
  3. the static CAP_PRODUCTION_APPROVAL_TOKEN supplied in X-Execution-Approval.

This is a second static factor, not two-person control, per-action approval, or a time-bounded authorization. High-risk deployments should put OpenAgentForce behind an external approval service or workflow that issues short-lived, operation-bound authorization.

Pub/Sub and Change Data Capture

The CDC worker authenticates to Salesforce Pub/Sub API, receives Avro events over gRPC/TLS, expands top-level and compound-field bitmaps against the exact event schema, stores replay IDs, and refreshes affected records before updating the graph.

Replay IDs and CDC payloads are sensitive operational data. Protect the graph database and logs as customer data. Configure CDC only for required objects and fields. OpenAgentForce persists its latest cursor, but Salesforce event retention remains an external platform constraint; prolonged downtime can require a bounded resynchronization.

Graph and learned-model boundary

The deterministic Salesforce graph is built from record IDs, lookup/master-detail metadata, and observed changes. The bundled Queen checkpoint was trained on a synthetic graph benchmark and is marked production_calibrated=false in every result.

In v0.5.1 the Queen may rank possible incident origins, but it must not independently authorize production writes. Any org-specific learned model should have a versioned training dataset, calibration report, approval record, rollback target, and explicit policy envelope.

Tenant and environment isolation

OpenAgentForce's control-plane records are tenant- and environment-scoped. Local business records use separate environment databases, and each Salesforce connector owns a separate Salesforce graph database. Sandbox and production Salesforce orgs should never share a connector or credential.

Generic outbound HTTP

The generic HTTP connector remains deny-by-default with host allowlisting, HTTPS enforcement, DNS/IP checks, redirect revalidation, response-size limits, and timeouts. Salesforce REST calls use the instance URL returned by the authenticated Salesforce token rather than arbitrary action-supplied destinations.

Signed bundles and replay

Agent bundles use canonical JSON, SHA-256, and Ed25519 signatures. Imports remain untrusted until reviewed. Decision replay uses trace-time snapshots and does not execute remote Salesforce writes.

Container

The Docker image runs as a non-root user, contains no default administrator credential, and the supplied Compose configuration binds to host loopback. Production deployments should additionally use a reverse proxy, TLS termination, network policy, database backups, centralized audit export, and monitored secret rotation.

Tested Salesforce security regressions

The suite covers:

  • JWT bearer assertion generation and token caching;
  • encrypted connector-secret storage;
  • connector-name/path traversal rejection;
  • Salesforce-origin URL enforcement;
  • object and field write rejection;
  • invalid picklist rejection;
  • external-ID enforcement;
  • sandbox/production authorization boundaries;
  • schema/FLS preflight before dispatch;
  • Composite subrequest path restriction;
  • idempotent Salesforce action replay;
  • concurrent idempotency protection in the common action layer;
  • unknown-outcome persistence;
  • evidence-bound reconciliation;
  • compensation state handling;
  • top-level and compound CDC bitmap decoding;
  • schema-derived relationship graph construction;
  • signed-bundle tamper detection and hermetic replay.

There aren't any published security advisories