Data Sources

A DataSource represents an external system — a cloud provider account, an HR platform, an identity provider, or any other source of entity data. Registering a data source lets cPod pull records into the EDM on demand or on a schedule, keeping your graph current without manual imports.


DataSource Schema

FieldTypeRequiredDescription
idstringautoPrefixed ID: ds-{ulid}
namestringyesDisplay name (e.g. “AWS Production Account”)
typeenumyesaws | gcp | azure | okta | workday | github | jira | custom
statusenumautoactive | error | disabled
configobjectyesProvider-specific connection config (see below)
lastSyncAtstringautoISO 8601 UTC timestamp of last successful sync
lastSyncStatusenumautosuccess | partial | failed
syncSchedulestringnoCron expression for automatic syncs
tagsstring[]noFree-form tags
createdAtstringautoISO 8601 UTC
⚠️

The config object may contain credentials. It is stored encrypted at rest and never returned in API responses — only the field names are echoed back, not values.


List & Get Data Sources

import { CpodClient } from '@cpod/sdk'
const sdk = CpodClient.fromEnv()
 
const result = await sdk.dataSources.list({ type: 'aws', limit: 20 })
for (const ds of result.items) {
  console.log(ds.id, ds.name, ds.status, ds.lastSyncAt)
}
 
const source = await sdk.dataSources.get('ds-abc123')

Register a Data Source

// AWS account via IAM role
const awsSource = await sdk.dataSources.create({
  name: 'AWS Production',
  type: 'aws',
  config: {
    accountId: '123456789012',
    roleArn: 'arn:aws:iam::123456789012:role/CpodReadOnly',
    regions: ['us-east-1', 'eu-west-1'],
  },
  syncSchedule: '0 2 * * *',  // daily at 02:00 UTC
})
 
// Okta identity provider
const oktaSource = await sdk.dataSources.create({
  name: 'Okta Production',
  type: 'okta',
  config: {
    domain: 'acme.okta.com',
    apiToken: process.env.OKTA_API_TOKEN,
  },
  syncSchedule: '0 * * * *',  // hourly
})

Update & Delete

// Update the sync schedule or config
await sdk.dataSources.update('ds-abc123', {
  syncSchedule: '0 */6 * * *',  // every 6 hours
})
 
// Disable a source without deleting it
await sdk.dataSources.update('ds-abc123', { status: 'disabled' })
 
await sdk.dataSources.delete('ds-abc123')

Trigger a Manual Sync

// Kick off an immediate sync
const job = await sdk.dataSources.sync('ds-abc123')
// job.id     → "job-01HXYZ..."
// job.status → "queued"
 
// Wait for completion (polls internally)
const result = await sdk.jobs.wait(job.id, { timeoutMs: 120_000 })
// result.output → { created: 34, updated: 12, deleted: 2, errors: 0 }
 
// Get sync history
const history = await sdk.dataSources.syncHistory('ds-abc123', { limit: 10 })
for (const entry of history.items) {
  console.log(entry.startedAt, entry.status, entry.output)
}