Connections
Securely manage credentials for external services
Connections
Connections are secure credential stores for external services. They abstract away authentication complexity and enable your actions and automations to interact with third-party APIs securely.
Concept
A connection combines:
- Provider — Service type (e.g.,
shopify,salesforce,postgresql) - Credentials — Encrypted secrets (API keys, OAuth tokens, passwords)
- Config — Non-secret settings (host, database, options)
- Status — Health state (active, error, pending, expired)
Key Features
| Feature | Description |
|---|---|
| Envelope Encryption | Credentials encrypted with DEK, DEK encrypted with KEK (AWS KMS) |
| Token Refresh | OAuth tokens automatically refreshed before expiry |
| Connection Testing | Verify connectivity before using in production |
| Flexible Resolution | Reference by ID, slug, or provider |
| Default Connections | Set one connection per provider as the default |
Connections are scoped to an organization. All members with appropriate permissions can use them.
Connection Types
OAuth Connections
For services like Salesforce, HubSpot, and Shopify that use OAuth2:
- User initiates OAuth flow
- Redirected to provider for authorization
- Provider returns authorization code
- VirtuousAI exchanges code for tokens
- Tokens stored encrypted
OAuth connections automatically refresh tokens before expiry.
API Key Connections
For services that use static API keys:
{
"name": "Production Database",
"provider": "postgresql",
"config": {
"host": "db.example.com",
"port": 5432,
"database": "production",
"ssl": true
},
"credentials": {
"username": "app_user",
"password": "secure_password"
}
}{
"name": "Stripe API",
"provider": "rest",
"config": {
"baseUrl": "https://api.stripe.com/v1",
"headers": {
"Content-Type": "application/json"
}
},
"credentials": {
"apiKey": "sk_live_..."
}
}{
"name": "Snowflake DW",
"provider": "snowflake",
"config": {
"account": "xy12345.us-east-1",
"warehouse": "COMPUTE_WH",
"database": "ANALYTICS",
"schema": "PUBLIC"
},
"credentials": {
"username": "ETL_USER",
"password": "...",
"role": "ETL_ROLE"
}
}Supported Providers
| Provider | Type | Auth Method | Use Case |
|---|---|---|---|
salesforce | CRM | OAuth2 | Sales data, leads, opportunities |
hubspot | CRM | OAuth2 | Marketing automation, contacts |
shopify | E-commerce | OAuth2 | Orders, products, customers |
klaviyo | Marketing | API Key | Email/SMS marketing, profiles, events |
postgresql | Database | Credentials | Data queries and updates |
mysql | Database | Credentials | Data queries and updates |
snowflake | Data Warehouse | Credentials | Analytics queries |
rest | Generic API | API Key | Any REST API |
graphql | Generic API | API Key | Any GraphQL API |
Connection Lifecycle
| Status | Description | Action Required |
|---|---|---|
pending | OAuth in progress | Complete OAuth flow |
active | Connection healthy | None |
error | Test failed | Check credentials |
expired | Token expired, refresh failed | Re-authenticate |
Connection Resolution
Actions and automations can reference connections flexibly:
| Reference Type | Example | How It Resolves |
|---|---|---|
| By ID | { "id": "conn_abc123" } | Exact connection match |
| By Slug | { "slug": "prod-shopify" } | Lookup by human-readable slug |
| By Provider | { "provider": "shopify" } | Uses org's default for that provider |
Examples
Reference a specific connection:
{
"actionTemplate": "sync-salesforce-leads",
"connectionRef": { "id": "conn_sf_production" }
}Use the default Salesforce connection:
{
"actionTemplate": "sync-salesforce-leads",
"connectionRef": { "provider": "salesforce" }
}LLM-friendly slug reference:
{
"actionTemplate": "extract-orders",
"connectionRef": { "slug": "shopify" }
}Security Model
Envelope Encryption
- Data Encryption Key (DEK) — Unique per connection, encrypts credentials
- Key Encryption Key (KEK) — AWS KMS key, encrypts DEKs
- Credentials never stored in plaintext
- Decryption only at runtime, in-memory
Access Control
- Connections are org-scoped
- Users need appropriate permissions to view/use
- Credentials are never exposed via API (only connection metadata)
Security
Never log or expose connection credentials. Use connection references in your code, and let VirtuousAI handle credential injection.
Best Practices
- Use descriptive names — Include environment (prod/staging) and purpose
- Test before use — Always verify connections work before using in automations
- Set defaults — Configure a default connection per provider for convenience
- Rotate credentials — Update API keys periodically for security
- Monitor status — Set up alerts for connection failures
OpenAPI Reference
For detailed endpoint schemas and response formats: