Skip to main content
Each recipe includes the problem, solution code, and rationale.

Per-connector ID formats

Problem: Different external systems use different ID formats. Knowing what value to use for RawId annotation is critical for correlation. Solution: Use the external system’s native stable identifier:
ConnectorID sourceFormatExample
Oktaapp.Id / group.Id20-char alphanumeric0oa1xyz789abcdef0h7
Azure ADObject ID (not App ID)UUID12345678-1234-1234-1234-123456789012
GCPResource pathprojects/{id}projects/my-project-123
AWSARNFull ARNarn:aws:iam::123456789012:role/Admin
GitHubNode ID or numeric IDInteger as string12345678
SalesforceSalesforce ID18-char ID00e3h000000bRQAAA2
Google WorkspaceGoogle Group IDVariable00gjdgxs3x1h123
Why this matters: ConductorOne uses these IDs to correlate resources across syncs. Using the wrong ID causes duplicate objects or failed correlations. Key points:
  • Azure AD has two IDs: Object ID (use this) and Application ID (client ID for OAuth)
  • AWS uses full ARNs, not account IDs alone
  • GitHub has numeric IDs and GraphQL node IDs; either works but be consistent

Setting RawId annotation

Problem: Ensure ConductorOne can correlate your resources across syncs and match resources created via Terraform. What is RawId? A string annotation containing the external system’s native identifier. ConductorOne uses this to match resources across syncs and to merge Terraform-created objects with connector-discovered ones. Solution: Add the RawId annotation when building resources:
// Inline with resource creation (preferred)
userResource, err := resource.NewUserResource(
    user.DisplayName,
    userResourceType,
    user.ID,
    userTraitOptions,
    resource.WithAnnotation(&v2.RawId{Id: user.ID}),
)

// Or add after creation
groupResource, err := resource.NewGroupResource(
    group.Name,
    groupResourceType,
    group.ID,
    groupTraitOptions,
)
groupResource.WithAnnotation(&v2.RawId{Id: group.Email})
What value to use: The external system’s native, stable identifier. Choose an ID that:
  • Won’t change when the resource is renamed or modified
  • Is unique within that resource type
  • Is what an admin would recognize from the external system

Examples from production connectors

SystemResourceRawId valueWhy
OktaUseruser.Id (00u1abc...)Okta’s internal ID, stable across renames
OktaAppapp.Id (0oa1xyz...)Okta’s internal app ID
Google WorkspaceUseruser.PrimaryEmailEmail is the canonical identifier
Google WorkspaceGroupgroup.EmailGroup email is stable and recognizable
GCPProjectproject.ProjectIdProject ID (not display name)
AWSRoleFull ARNARNs are globally unique
Azure ADUserObject ID (UUID)Not the UPN, which can change

Common mistakes

MistakeProblemFix
Using display namesChange when renamedUse system-generated IDs
Using array indicesChange with orderingUse stable identifiers
Different IDs for same resourceCorrelation failsUse consistent ID source
Using mutable fieldsResource appears as new each syncUse immutable system IDs

When to use RawId

Should have RawId:
  • Apps, groups, roles, and any resource that might be pre-created via Terraform
  • Resources that need stable correlation across syncs
  • Any resource type where admins might reference objects by external ID
May not need RawId:
  • Ephemeral or derived resources
  • Resources only used internally by the connector

Next