Security review, CRUD/FLS enforcement, tenant isolation, and audit requirements are not features added later. They are built into the WeaveOps architecture from the start. This page documents what those controls are and how they work.
For a Salesforce AppExchange security review or enterprise procurement process, email [email protected].
WeaveOps uses the Salesforce External Credential and Named Credential framework for all outbound callouts. The API key used to authenticate with the WeaveOps service layer is stored as an External Credential principal — encrypted by Salesforce, never accessible via SOQL, and never referenced in Apex source code. Admins configure the key once in Salesforce Setup. Developers never see it.
The Anthropic API key used to call Claude is stored as an Azure App Service environment variable. It is not in Salesforce, not in any config file in the repo, and not in the request payload from Salesforce. It lives only in the Azure runtime environment, managed by the WeaveOps service administrator.
Each Salesforce org connected to the WeaveOps service has its own API key. Keys can be rotated independently without affecting other tenants. Rotation requires updating the External Credential principal in Salesforce Setup and registering the new key via the WeaveOps admin endpoint.
Every field read and record write in WeaveOps Apex code is validated against the running user's Salesforce permissions before it executes. Object-level create, read, update, and delete permissions are checked explicitly. Field-level security is enforced using Security.stripInaccessible() on all query results. Users cannot read or write fields their Salesforce profile does not permit.
All user-facing Apex classes run with sharing (with sharing keyword). Users only see records they are entitled to see under Salesforce's sharing rules. Background queueables and schedulers that must access admin-only configuration objects run without sharing, with explicit justification documented in the class header.
WeaveOps ships with two permission sets: WeaveOps Admin (full access to configuration objects, admin console, and analytics) and WeaveOps User (access to runtime components only — cannot read use case configuration, instruction sets, or error logs). Sensitive fields like Error_Log__c and Azure_Endpoint__c are hidden from the user permission set.
The WeaveOps service layer uses Python's hmac.compare_digest() for all API key comparisons — both the admin key and tenant key resolution. This prevents timing attacks where an attacker could infer correct key characters by measuring response time differences.
All AI service endpoints are rate-limited using Flask-Limiter. Limits are applied per tenant ID, not per IP address. This means a single compromised tenant key cannot exhaust the service's capacity or increase costs for other tenants. Default limits: 500 requests/hour, 60 requests/minute on execute endpoints.
All user-supplied text fields sent to the AI service are validated for maximum length (50,000 characters by default) before the request is processed. Oversized inputs return a 400 error and are never forwarded to the AI model. This prevents prompt flooding and controls cost exposure.
The WeaveOps service layer sanitises all error responses before returning them to callers. Internal exception details, file paths, stack traces, and Python type names are stripped. Callers receive only a safe, generic error message. Internal details are logged server-side for debugging.
The WeaveOps Azure service runs in a Docker container as a non-root user (appuser). This follows the principle of least privilege for container security and is a standard requirement for production container deployments.
Each Salesforce org connected to WeaveOps has its own isolated namespace in Azure Blob Storage. Interaction logs, instruction files, and configuration assets are stored under the tenant's org ID prefix. One tenant cannot read or affect another tenant's data.
Interaction logs (prompt, response, duration, model metadata) are stored in Azure Blob Storage. Log retention is configurable via the LOG_RETENTION_DAYS environment variable (default: 90 days). A built-in purge endpoint allows on-demand deletion of logs outside the retention window, supporting GDPR data minimisation requirements.
WeaveOps logs: the assembled prompt sent to the model, the model's response, call duration, token counts, model version, success/failure status, and tenant ID. WeaveOps does not log Salesforce user identities, raw Salesforce field data, or file contents. Logs are used for debugging, usage analytics, and billing.
Every AI call initiated through a WeaveOps component creates a Conversation or Batch Run record in Salesforce. These records capture the use case, timing, processing status, and any error information. They are stored in your Salesforce org, subject to your normal retention and audit policies.
WeaveOps is distributed as a Salesforce second-generation managed package (2GP) with a registered namespace. All custom objects, fields, Apex classes, and LWC components are namespaced, preventing conflicts with other packages or custom development in the subscriber org.
WeaveOps includes a post-install handler that assigns the admin permission set to the installing user and runs idempotent setup steps on upgrade. An uninstall handler deletes transactional records (Conversations, Batch Runs, Pipeline Runs) before package removal, meeting AppExchange cleanup requirements.
The WeaveOps codebase passes Salesforce Code Analyzer on the AppExchange and Recommended:Security rulesets with zero Critical or High violations. Code Analyzer runs automatically on every push to the force-app directory via GitHub Actions.
For AppExchange security review materials, enterprise security questionnaires, penetration test coordination, or data flow documentation, contact us directly.
[email protected]