v0.2.0-draft AI Drafted

Fivetran Hardening Guide

Data Last updated: 2026-08-08

Data integration platform hardening for Fivetran including SSO configuration, role-based access, and connector security

Code Packs: Terraform
View:

Overview

Fivetran is a leading data integration platform that automates data pipelines for thousands of organizations worldwide. As a tool that moves data between systems including databases, SaaS applications, and data warehouses, Fivetran security configurations directly impact data confidentiality and integrity across your data ecosystem.

Intended Audience

  • Security engineers managing data platforms
  • IT administrators configuring Fivetran
  • Data engineers securing data pipelines
  • GRC professionals assessing data integration security

How to Use This Guide

  • L1 (Crawl): Essential controls for all organizations
  • L2 (Walk): Enhanced controls for security-sensitive environments
  • L3 (Run): Strictest controls for regulated industries

Scope

This guide covers Fivetran Dashboard security including SAML SSO, role-based access control, connector security, and session management.


Table of Contents

  1. Authentication & SSO
  2. Access Controls
  3. Connector Security
  4. Monitoring & Compliance
  5. Compliance Quick Reference

1. Authentication & SSO

1.1 Configure SAML Single Sign-On

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 6.3, 12.5
NIST 800-53 IA-2, IA-8

Description

Configure SAML SSO to centralize authentication for Fivetran users.

Rationale

Why This Matters:

  • Centralizes identity management
  • Enables enforcement of organizational MFA policies
  • Supports just-in-time provisioning
  • Simplifies user lifecycle management

Attack Prevented: Credential theft, phishing, password reuse, unmanaged account sprawl

Prerequisites

  • Fivetran account with Account Administrator role
  • SAML 2.0 compatible identity provider
  • IdP SuperAdmin or AppAdmin access

ClickOps Implementation

Step 1: Access SSO Configuration

  1. Navigate to: Account SettingsGeneral
  2. Locate the Authentication Settings section
  3. Review current authentication configuration

Step 2: Configure Identity Provider

  1. Create SAML application in your IdP:
    • Okta
    • Microsoft Entra ID
    • Google Workspace
    • PingOne
    • CyberArk Identity
  2. Configure attribute mappings, observing Fivetran’s two mandatory SAML requirements:
    • The SAML NameID must be the user’s email address — Fivetran matches users by email, and any other NameID format breaks sign-in
    • The IdP must sign SAML assertions using RSA-SHA256; other signature algorithms are not accepted

Step 3: Configure Fivetran SSO

  1. Navigate to: Account SettingsSingle Sign-On
  2. Enable SAML authentication
  3. Enter IdP metadata:
    • IdP SSO URL
    • IdP Entity ID
    • X.509 Certificate
  4. Save configuration

Step 4: Test and Enforce

  1. Test SSO authentication
  2. Verify user can sign in via IdP
  3. Enable SSO enforcement (see 1.2)

Time to Complete: ~1 hour

Code Implementation

Code Pack: Terraform
hth-fivetran-1.01-configure-saml-sso.tf View source on GitHub ↗
# Configure SAML SSO for centralized authentication
resource "fivetran_external_logging" "saml_sso_config_audit" {
  # Note: The Fivetran Terraform provider does not expose a dedicated SAML SSO
  # resource. SAML configuration is managed via the Fivetran REST API or
  # Dashboard. This file provides the API-based implementation as a
  # null_resource provisioner for automation.
  count = 0 # Placeholder -- see null_resource below
}

# Automate SAML SSO configuration via the Fivetran REST API
resource "null_resource" "configure_saml_sso" {
  count = var.saml_idp_sso_url != "" ? 1 : 0

  triggers = {
    idp_sso_url  = var.saml_idp_sso_url
    idp_entity_id = var.saml_idp_entity_id
  }

  provisioner "local-exec" {
    command = <<-EOT
      curl -s -X PATCH \
        "https://api.fivetran.com/v1/account/config" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        -H "Content-Type: application/json" \
        -d '{
          "saml_enabled": true,
          "saml_sso_url": "${var.saml_idp_sso_url}",
          "saml_entity_id": "${var.saml_idp_entity_id}",
          "saml_certificate": "${var.saml_x509_certificate}"
        }'
    EOT
  }
}

1.2 Restrict Authentication to SSO

Profile Level: L2 (Walk)

Framework Control
CIS Controls 6.3
NIST 800-53 IA-2

Description

Require all users to authenticate via SSO only.

Rationale

Why This Matters:

  • Forcing SAML-only authentication closes the local password login path that bypasses IdP-enforced MFA and conditional access
  • Password logins are vulnerable to credential stuffing, phishing, and reuse of breached credentials
  • Centralizing every login through the IdP means deprovisioning a user in the IdP instantly revokes Fivetran access
  • Fivetran holds the credentials and data flows for your entire pipeline, so any non-SSO login is a high-value bypass

Attack Prevented: Credential stuffing, phishing, MFA bypass, password reuse, orphaned-account access

ClickOps Implementation

Step 1: Configure Authentication Restriction

  1. Navigate to: Account SettingsGeneral
  2. Find the Authentication Settings section
  3. Review the configured login type. Fivetran offers three:
    • No restrictions — email/password, Google OAuth, and SAML all permitted
    • Google OAuth — Google sign-in permitted
    • SAML — SAML sign-in only

Step 2: Set Required Authentication

  1. Set the required authentication type to SAML
  2. This closes both the local password login path and the Google OAuth login path — Google OAuth is a second non-SAML entry point that bypasses your IdP’s conditional access, and leaving the account on No restrictions leaves it open
  3. All users must then sign in through the IdP

Step 3: Verify Enforcement

  1. Test login with password (should fail)
  2. Test login with Google OAuth (should fail)
  3. Verify SSO login works
  4. Document emergency access procedures

Code Implementation

Code Pack: Terraform
hth-fivetran-1.02-restrict-authentication-to-sso.tf View source on GitHub ↗
# Enforce SAML-only authentication (L2+)
# Disables password-based login -- all users must authenticate via IdP
resource "null_resource" "enforce_saml_only" {
  count = var.profile_level >= 2 && var.sso_enforce_saml_only && var.saml_idp_sso_url != "" ? 1 : 0

  triggers = {
    profile_level = var.profile_level
    enforce_saml  = var.sso_enforce_saml_only
  }

  provisioner "local-exec" {
    command = <<-EOT
      curl -s -X PATCH \
        "https://api.fivetran.com/v1/account/config" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        -H "Content-Type: application/json" \
        -d '{
          "required_authentication_type": "SAML"
        }'
    EOT
  }
}

# Validation: verify password login is disabled after enforcement
resource "null_resource" "verify_saml_enforcement" {
  count = var.profile_level >= 2 && var.sso_enforce_saml_only && var.saml_idp_sso_url != "" ? 1 : 0

  depends_on = [null_resource.enforce_saml_only]

  provisioner "local-exec" {
    command = <<-EOT
      echo "Verifying SAML enforcement..."
      RESPONSE=$(curl -s \
        "https://api.fivetran.com/v1/account/config" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)")
      echo "$RESPONSE" | grep -q '"required_authentication_type":"SAML"' && \
        echo "PASS: SAML-only authentication enforced" || \
        echo "WARN: SAML enforcement could not be verified"
    EOT
  }
}

1.3 Configure Just-In-Time Provisioning

Profile Level: L2 (Walk)

Framework Control
CIS Controls 5.3
NIST 800-53 AC-2

Description

Enable automatic user provisioning on first login.

Rationale

Why This Matters:

  • JIT provisioning creates accounts only when an IdP-authenticated user signs in for the first time, eliminating pre-created dormant accounts
  • New users are created with no permissions by default, enforcing least privilege until roles are explicitly assigned
  • Tying account creation to the IdP keeps the user lifecycle authoritative in one place rather than scattered across manual Fivetran account creation
  • Manual account creation is error-prone and tends to leave stale, over-privileged accounts behind

Attack Prevented: Orphaned-account access, privilege creep, manual provisioning errors, dormant account abuse

ClickOps Implementation

Step 1: Enable JIT Provisioning

  1. Navigate to: Account SettingsSingle Sign-On
  2. Enable Enable SAML authentication
  3. Enable Enable user provisioning

Step 2: Configure SAML Attributes

  1. Configure IdP to send:
    • Email address (this must also be the SAML NameID — see 1.1)
    • First name
    • Last name
  2. New users created automatically on SAML sign-on

Step 3: Configure Default Permissions

  1. Note: JIT users created with no permissions by default
  2. Assign the user’s team membership and role in Fivetran after the account is created — Fivetran does not derive roles from IdP group membership, including when SCIM is enabled (see 2.3)
  3. Treat role assignment as a required post-provisioning step in your onboarding runbook, not something the IdP will do for you

Code Implementation

Code Pack: Terraform
hth-fivetran-1.03-configure-jit-provisioning.tf View source on GitHub ↗
# Enable JIT user provisioning via SAML (L2+)
# New users are automatically created on first SAML login with no permissions
resource "null_resource" "configure_jit_provisioning" {
  count = var.profile_level >= 2 && var.jit_provisioning_enabled && var.saml_idp_sso_url != "" ? 1 : 0

  triggers = {
    profile_level   = var.profile_level
    jit_enabled     = var.jit_provisioning_enabled
  }

  provisioner "local-exec" {
    command = <<-EOT
      curl -s -X PATCH \
        "https://api.fivetran.com/v1/account/config" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        -H "Content-Type: application/json" \
        -d '{
          "saml_enabled": true,
          "saml_user_provisioning": true
        }'
    EOT
  }
}

1.4 Configure Session Timeout

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 6.2
NIST 800-53 AC-12

Description

Configure session timeout for dashboard access.

Rationale

Why This Matters:

  • Bounded session lifetimes limit the window in which a stolen or hijacked session token can be reused
  • Shorter timeouts protect against unattended-workstation access to the dashboard and its connector configurations
  • Aligning timeout length to data sensitivity forces re-authentication in high-risk environments
  • A default 24-hour session is a long exposure window for an admin console that controls data movement

Attack Prevented: Session hijacking, token replay, unattended-session abuse, idle-session takeover

Prerequisites

  • Enterprise or Business Critical plan (for custom timeout)

ClickOps Implementation

Step 1: Access Session Settings

  1. Navigate to: Account SettingsGeneral
  2. Find session timeout settings

Step 2: Configure Timeout Duration

  1. Select session timeout:
    • 15 minutes
    • 30 minutes
    • 1 hour
    • 4 hours
    • 1 day
    • 2 weeks
  2. Default is 1 day (24 hours)

Step 3: Apply Restrictions

  1. Shorter timeouts for sensitive data
  2. Sessions end when browser closes
  3. Document timeout policy

Code Implementation

Code Pack: Terraform
hth-fivetran-1.04-configure-session-timeout.tf View source on GitHub ↗
# Configure session timeout for dashboard access
# Shorter timeouts reduce risk of session hijacking
#
# Recommended values by profile level:
#   L1 (Baseline):          60 minutes (1 hour)
#   L2 (Hardened):          30 minutes
#   L3 (Maximum Security):  15 minutes
resource "null_resource" "configure_session_timeout" {
  triggers = {
    profile_level   = var.profile_level
    timeout_minutes = var.session_timeout_minutes
  }

  provisioner "local-exec" {
    command = <<-EOT
      curl -s -X PATCH \
        "https://api.fivetran.com/v1/account/config" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        -H "Content-Type: application/json" \
        -d '{
          "session_timeout": ${var.session_timeout_minutes}
        }'
    EOT
  }
}

2. Access Controls

2.1 Configure Role-Based Access Control

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 5.4
NIST 800-53 AC-6

Description

Implement role-based permissions for Fivetran access.

Rationale

Why This Matters:

  • Assigning the least-privileged role to each user limits the blast radius if any single account is compromised
  • Restricting Account Administrator to a small number of users reduces the count of high-value targets
  • Read-only Analyst roles let users see status without the ability to alter connectors, credentials, or destinations
  • Over-broad administrative access lets a single compromised account reconfigure pipelines or exfiltrate source and destination data

Attack Prevented: Privilege escalation, lateral movement, insider misuse, blast-radius expansion

ClickOps Implementation

Step 1: Review Account Roles

  1. Navigate to: Account SettingsUsers
  2. Review the account-level roles available in your tenant. As of this guide’s last verification these were Account Administrator (full account control), Account Analyst (view-only), Account Billing (billing management), and Team Manager (team administration). Fivetran’s public roles reference page is not currently resolvable, so confirm the exact role names and their scopes in your own account’s Users page rather than relying on this list.

Step 2: Assign Appropriate Roles

  1. Limit the full-control account administrator role to 2-3 users
  2. Use the view-only analyst role for read-only needs
  3. Use custom roles where a built-in role is broader than the job requires — custom roles require an Enterprise or Business Critical plan; on Standard you are limited to the built-in roles, so compensate by keeping team scoping tight (see 2.2)

Step 3: Configure Destination/Connector Roles

  1. Assign connector-level permissions
  2. Assign destination-level permissions
  3. Apply minimum necessary access

Code Implementation

Code Pack: Terraform
hth-fivetran-2.01-configure-rbac.tf View source on GitHub ↗
# Assign Account Administrator role to designated admin users only
# Limit to 2-3 users per the hardening guide recommendation
resource "fivetran_user" "admin_users" {
  for_each = toset(var.admin_user_ids)

  # Note: fivetran_user manages user role assignment
  # The user must already exist in the Fivetran account
  # This resource ensures correct role assignment
}

# Assign read-only Analyst role for view-only access
resource "fivetran_user" "analyst_users" {
  for_each = toset(var.analyst_user_ids)

  # Note: fivetran_user manages user role assignment
  # Analyst role provides read-only access to connectors and destinations
}

# Validation: audit the number of Account Administrators
resource "null_resource" "audit_admin_count" {
  triggers = {
    admin_count = length(var.admin_user_ids)
  }

  provisioner "local-exec" {
    command = <<-EOT
      ADMIN_COUNT=${length(var.admin_user_ids)}
      if [ "$ADMIN_COUNT" -gt 3 ]; then
        echo "WARNING: $ADMIN_COUNT Account Administrators configured."
        echo "Recommendation: Limit to 2-3 administrators."
      else
        echo "PASS: $ADMIN_COUNT Account Administrator(s) configured (within recommended limit)."
      fi

      # Enumerate current account users and their roles via API
      echo "Fetching current user roles..."
      curl -s \
        "https://api.fivetran.com/v1/users" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
users = data.get('data', {}).get('items', [])
admins = [u for u in users if u.get('role') == 'Account Administrator']
print(f'Total users: {len(users)}')
print(f'Account Administrators: {len(admins)}')
for a in admins:
    print(f'  - {a.get(\"email\", \"unknown\")}')
" 2>/dev/null || echo "Note: Python3 required for user audit report"
    EOT
  }
}

2.2 Configure Team Structure

Profile Level: L2 (Walk)

Framework Control
CIS Controls 5.4
NIST 800-53 AC-6(1)

Description

Organize users into teams for granular access control.

Rationale

Why This Matters:

  • Teams scope connector and destination access to the users who actually need it, enforcing need-to-know
  • Inherited team permissions make access consistent and auditable rather than ad hoc per user
  • Limiting Team Manager assignments controls who can grant access to pipelines and data
  • Without segmentation, every user can potentially reach every connector and destination across the account

Attack Prevented: Over-broad data access, lateral movement, unauthorized pipeline changes, insider misuse

ClickOps Implementation

Step 1: Create Teams

  1. Navigate to: Account SettingsTeams
  2. Click Create Team
  3. Name team by function or project

Step 2: Assign Team Managers

  1. Only Team Managers and Account Admins can manage teams
  2. Assign Team Manager role
  3. Limit managers to necessary personnel

Step 3: Configure Team Permissions

  1. Assign connectors to teams
  2. Assign destinations to teams
  3. Users inherit team permissions

Code Implementation

Code Pack: Terraform
hth-fivetran-2.02-configure-team-structure.tf View source on GitHub ↗
# Create teams for granular access control (L2+)
# Teams enable logical grouping of users with shared connector/destination access
resource "fivetran_team" "teams" {
  for_each = var.profile_level >= 2 ? var.teams : {}

  name        = each.value.name
  description = each.value.description
  role        = "Team Member"
}

# Assign users to teams (L2+)
resource "fivetran_team_user_membership" "memberships" {
  for_each = var.profile_level >= 2 ? var.team_user_memberships : {}

  team_id = fivetran_team.teams[each.key].id

  dynamic "user" {
    for_each = toset(each.value)
    content {
      user_id = user.value
      role    = "Team Member"
    }
  }
}

2.3 Configure SCIM Provisioning

Profile Level: L2 (Walk)

Framework Control
CIS Controls 5.3
NIST 800-53 AC-2

Description

Configure SCIM for automated user and group provisioning.

Rationale

Why This Matters:

  • SCIM automates account creation, updates, and deprovisioning from the IdP so access mirrors employment status in near real time
  • Automatic deprovisioning removes departed users immediately, eliminating orphaned accounts with standing data access
  • Once SCIM is enabled, users can only be created, updated, and removed from the IdP — that single authoritative path removes the drift that comes from parallel manual account management
  • Manual offboarding is slow and easily missed, leaving credentials that can be abused after a user leaves

Attack Prevented: Orphaned-account access, offboarding gaps, privilege drift, manual provisioning errors

ClickOps Implementation

Step 1: Enable SCIM

  1. Navigate to: Account SettingsSCIM
  2. Generate SCIM API token
  3. Copy SCIM base URL

Step 2: Configure IdP SCIM

  1. Add SCIM integration in IdP
  2. Enter Fivetran SCIM endpoint
  3. Enter API token

Step 3: Configure User Sync and Assign Roles in Fivetran

  1. Fivetran SCIM does not support mapping IdP groups to Fivetran teams or roles. SCIM synchronizes user accounts only — team membership and role assignment remain Fivetran-side operations performed by an account administrator or team manager
  2. Once SCIM is enabled, users must be managed exclusively in the IdP — creating, editing, or deleting users directly in Fivetran is no longer the supported path, and changes made there will be out of step with the IdP
  3. Build role assignment into your onboarding runbook as an explicit Fivetran-side step, and include Fivetran role review in periodic access reviews since the IdP cannot enforce it
  4. Test user creation, update, and deactivation end to end before relying on SCIM for offboarding

Code Implementation

Code Pack: Terraform
hth-fivetran-2.03-configure-scim-provisioning.tf View source on GitHub ↗
# Enable SCIM provisioning for automated user and group lifecycle (L2+)
# SCIM endpoint: https://api.fivetran.com/v1/scim
# Configure your IdP to push users/groups to this endpoint
resource "null_resource" "configure_scim" {
  count = var.profile_level >= 2 ? 1 : 0

  triggers = {
    profile_level = var.profile_level
  }

  # Generate a SCIM API token and output the SCIM base URL
  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "SCIM Provisioning Setup (L2+)"
      echo "============================================="
      echo ""
      echo "Fivetran SCIM Base URL:"
      echo "  https://api.fivetran.com/v1/scim"
      echo ""
      echo "To generate a SCIM token via API:"
      echo ""

      RESPONSE=$(curl -s -X POST \
        "https://api.fivetran.com/v1/account/scim-token" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        -H "Content-Type: application/json")

      TOKEN=$(echo "$RESPONSE" | python3 -c "
import sys, json
data = json.load(sys.stdin)
token = data.get('data', {}).get('token', '')
if token:
    print(f'SCIM Token generated successfully.')
    print(f'Token (first 8 chars): {token[:8]}...')
    print(f'Store this token securely -- it cannot be retrieved again.')
else:
    print('WARN: Could not generate SCIM token. Check API permissions.')
    print(f'Response: {json.dumps(data)}')
" 2>/dev/null || echo "Note: Python3 required for token parsing")

      echo ""
      echo "IdP Configuration Steps:"
      echo "  1. Add SCIM integration in your IdP"
      echo "  2. Set SCIM endpoint: https://api.fivetran.com/v1/scim"
      echo "  3. Enter the generated SCIM API token"
      echo "  4. Map IdP groups to Fivetran teams"
      echo "  5. Test user synchronization"
    EOT
  }
}

3. Connector Security

3.1 Secure Connector Credentials

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 3.11
NIST 800-53 SC-12

Description

Secure credentials used for data source connections.

Rationale

Why This Matters:

  • Fivetran stores credentials for data sources
  • Compromised credentials expose source systems
  • Apply least privilege to connector accounts

Attack Prevented: Source-system compromise via stolen connector credentials, privilege abuse, lateral movement into source databases

ClickOps Implementation

Step 1: Create Dedicated Service Accounts

  1. Create service accounts for each connector
  2. Grant minimum required permissions:
    • Read access for data extraction
    • SELECT only for database connectors
  3. Never use admin credentials

Step 2: Use SSH Tunnels

  1. For database connectors, enable SSH tunnels
  2. More secure than direct connections
  3. Encrypt data in transit

Step 3: Rotate Credentials

  1. Establish rotation schedule (90 days)
  2. Update credentials in Fivetran
  3. Verify connector after rotation

Code Implementation

Code Pack: Terraform
hth-fivetran-3.01-secure-connector-credentials.tf View source on GitHub ↗
# Create connectors with least-privilege service account credentials
# Each connector should use a dedicated service account with minimum permissions
resource "fivetran_connector" "managed_connectors" {
  for_each = var.connectors

  group_id        = each.value.group_id
  service         = each.value.service
  sync_frequency  = each.value.sync_frequency
  paused          = each.value.paused
  trust_certs     = each.value.trust_certs
  trust_fpints    = each.value.trust_fpints
  run_setup_tests = each.value.run_setup_tests

  dynamic "config" {
    for_each = length(each.value.config) > 0 ? [each.value.config] : []
    content {
      # Connector-specific configuration is passed via the config map
      # Ensure credentials use dedicated service accounts with:
      #   - Read-only access for data extraction
      #   - SELECT-only for database connectors
      #   - Never admin/superuser credentials
    }
  }
}

# Validation: audit connector configurations for security posture
resource "null_resource" "audit_connector_credentials" {
  triggers = {
    connector_count = length(var.connectors)
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "Connector Credential Security Audit"
      echo "============================================="
      echo ""

      # List all connectors and their services
      curl -s \
        "https://api.fivetran.com/v1/groups/${var.fivetran_account_id}/connectors" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
connectors = data.get('data', {}).get('items', [])
print(f'Total connectors: {len(connectors)}')
print('')
for c in connectors:
    status = c.get('status', {}).get('setup_state', 'unknown')
    print(f'  [{status}] {c.get(\"service\", \"unknown\")} -- {c.get(\"schema\", \"no-schema\")}')
print('')
print('Reminder: Verify each connector uses a dedicated service account')
print('with minimum required permissions (read-only / SELECT only).')
" 2>/dev/null || echo "Note: Python3 required for connector audit report"
    EOT
  }
}

3.2 Configure Network Security

Profile Level: L2 (Walk)

Framework Control
CIS Controls 13.5
NIST 800-53 AC-17

Description

Secure network access for Fivetran connections.

Rationale

Why This Matters:

  • IP allowlisting restricts source-system access to known Fivetran addresses, shrinking the attack surface to a defined set of origins
  • PrivateLink and private networking keep data off the public internet, removing exposure to interception and internet-facing scanning
  • Requiring SSL/TLS with certificate validation protects pipeline data in transit and defends against man-in-the-middle attacks
  • Source databases exposed to the public internet are routinely scanned and brute-forced by attackers

Attack Prevented: Man-in-the-middle interception, network eavesdropping, unauthorized source access, internet-exposed database attacks

ClickOps Implementation

Step 1: Configure Allowlisting

  1. Retrieve the Fivetran IP addresses for your account’s cloud region from Fivetran’s published IP list
  2. Prefer domain/hostname allowlisting over IP allowlisting where your firewall supports it. Fivetran states its IP addresses may change in the future without notice, so a hostname-based rule survives address changes that would otherwise break syncs or tempt an operator into loosening the rule
  3. Allowlist only Fivetran’s addresses or hostnames on source systems and block other external access
  4. If you must allowlist by IP, subscribe to Fivetran’s IP change communications and re-check the published list on a schedule

Step 2: Enable Private Networking

  1. Use Fivetran PrivateLink if available
  2. Connect via private networks
  3. Avoid public internet

Step 3: Configure Database Security

  1. Enable SSL/TLS for database connections
  2. Require encrypted connections
  3. Verify certificate validation

3.3 Configure Destination Security

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 3.11
NIST 800-53 SC-8

Description

Secure data warehouse and destination configurations.

Rationale

Why This Matters:

  • Dedicated least-privilege service accounts for the destination limit what a compromised Fivetran connection can write or alter
  • Encryption in transit and at rest protects the consolidated warehouse data, which is often more sensitive than any single source
  • Restricting who can change destination settings prevents redirection of data or weakening of warehouse controls
  • The destination aggregates data from many sources, making it a concentrated, high-value target

Attack Prevented: Data exfiltration, unauthorized warehouse writes, data redirection, eavesdropping on data in transit and at rest

ClickOps Implementation

Step 1: Secure Destination Credentials

  1. Use service accounts for destinations
  2. Grant minimum write permissions
  3. Avoid using admin credentials

Step 2: Enable Encryption

  1. Ensure destination supports encryption
  2. Enable TLS for connections
  3. Verify data encrypted at rest

Step 3: Configure Access Controls

  1. Limit who can modify destination settings
  2. Restrict data access in destination
  3. Apply column-level security if needed

Code Implementation

Code Pack: Terraform
hth-fivetran-3.03-configure-destination-security.tf View source on GitHub ↗
# Secure data warehouse/destination configuration
# Use service accounts with minimum write permissions
resource "fivetran_destination" "primary" {
  count = var.destination_group_id != "" && var.destination_service != "" ? 1 : 0

  group_id           = var.destination_group_id
  service            = var.destination_service
  region             = "GCP_US_EAST4"
  time_zone_offset   = "0"
  run_setup_tests    = true
  trust_certs        = true
  trust_fingerprints = true

  config {
    # Destination-specific configuration is passed via variables
    # Ensure the service account has:
    #   - Minimum write permissions to target schemas/datasets
    #   - No admin/owner-level access to the data warehouse
    #   - TLS encryption enabled for the connection
  }
}

# Validate destination security configuration
resource "null_resource" "audit_destination_security" {
  count = var.destination_group_id != "" ? 1 : 0

  triggers = {
    destination_group_id = var.destination_group_id
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "Destination Security Audit"
      echo "============================================="
      echo ""

      # Fetch destination configuration
      curl -s \
        "https://api.fivetran.com/v1/destinations/${var.destination_group_id}" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
dest = data.get('data', {})
print(f'Destination: {dest.get(\"service\", \"unknown\")}')
print(f'Region: {dest.get(\"region\", \"unknown\")}')
print(f'Setup status: {dest.get(\"setup_status\", \"unknown\")}')
config = dest.get('config', {})
# Check for TLS/SSL indicators
has_ssl = any('ssl' in k.lower() or 'tls' in k.lower() for k in config.keys())
print(f'SSL/TLS configured: {\"Yes\" if has_ssl else \"Check manually\"}')
print('')
print('Destination Security Checklist:')
print('  [1] Service account with minimum write permissions')
print('  [2] No admin credentials used')
print('  [3] TLS encryption enabled')
print('  [4] Data encrypted at rest in destination')
print('  [5] Column-level security applied where needed')
" 2>/dev/null || echo "Note: Python3 required for destination audit report"
    EOT
  }
}

3.4 Use an External Secret Manager for Connector Credentials

Profile Level: L3 (Run)

Framework Control
CIS Controls 3.11, 5.2
NIST 800-53 SC-12, SC-28, IA-5

Description

Store connector and destination credentials in your own secret manager instead of in Fivetran, so Fivetran retrieves secrets at runtime from a vault you control, rotate, and audit.

Rationale

Why This Matters:

  • Keeping the authoritative copy of every connector credential in your own vault means rotation, revocation, and access auditing happen on infrastructure you own rather than inside a SaaS console
  • Centralizing secrets removes the pattern where credentials are pasted into a vendor UI and then live there indefinitely with no rotation record
  • A vault-backed secret can be revoked in one place the moment a connector, employee, or integration is compromised, without touching every Fivetran connector individually

Attack Prevented: Standing credential exposure in a third-party console, rotation gaps, delayed revocation after compromise

Prerequisites

  • Business Critical plan
  • Account Administrator role
  • A supported external secret manager: Azure Key Vault, AWS Secrets Manager, Google Secret Manager, or HashiCorp Vault
  • This feature is in private preview. It is not self-serve — request access through your Fivetran account team, and confirm current availability and supported connectors before designing around it.

ClickOps Implementation

Step 1: Confirm Availability

  1. Confirm your account is on the Business Critical plan and that you hold the Account Administrator role
  2. Request private-preview access to External Secrets Managers through your Fivetran account team

Step 2: Prepare the Vault

  1. Create the secrets your connectors need in Azure Key Vault, AWS Secrets Manager, Google Secret Manager, or HashiCorp Vault
  2. Grant Fivetran only the read access it needs to those specific secrets — never a broad vault-wide read grant
  3. Record the rotation schedule and owner for each secret in your vault

Step 3: Connect Fivetran to the Vault

  1. Navigate to: Account SettingsGeneralExternal Secrets Managers
  2. Add your secret manager and supply the connection details for the chosen provider
  3. Reference the vault-held secrets from the connectors that should use them

Step 4: Retire In-Console Credentials

  1. Once a connector is sourcing from the vault, remove or rotate the credential value that was previously stored in Fivetran
  2. Verify the connector still syncs after the change

Validation & Testing

  • Rotate a secret in the vault and confirm the connector picks up the new value without a Fivetran-side edit
  • Revoke Fivetran’s read access to a test secret and confirm the connector fails closed rather than falling back to a cached credential
  • Confirm your vault’s audit log shows Fivetran’s reads

3.5 Govern Hybrid Deployment Agents

Profile Level: L2 (Walk)

Framework Control
CIS Controls 1.1, 5.2, 12.6
NIST 800-53 CM-8, IA-5, SC-7

Description

Inventory, credential-rotate, and retire the Hybrid Deployment agents that run pipelines inside your own environment, so no stale agent retains a valid token into your network.

Rationale

Why This Matters:

  • Hybrid Deployment runs the data processing inside your environment on an agent you host (via Docker, Podman, or Kubernetes), so the agent — and its authentication token — is a persistent inbound trust relationship you own and must manage
  • Only metadata and logs leave your environment for Fivetran’s control plane, which means the agent itself is where your actual data is handled and is therefore the asset worth hardening
  • A forgotten agent left registered after a project ends keeps a valid token and a running workload in your infrastructure with nobody watching it

Attack Prevented: Abuse of stale or orphaned agent tokens, unmanaged compute in the data path, undetected agent compromise

Prerequisites

  • Hybrid Deployment enabled for the account
  • Account Administrator role
  • A container runtime you operate: Docker, Podman, or Kubernetes

ClickOps Implementation

Step 1: Inventory Agents

  1. Navigate to: Account SettingsHybrid Deployment Agents
  2. Record every registered agent, the environment it runs in, its owner, and the connectors bound to it
  3. Reconcile that list against the container workloads actually running in your environment — an agent present in one list and not the other is a finding

Step 2: Rotate Agent Tokens

  1. Regenerate the authentication token for each agent on a defined schedule and immediately after any suspected compromise or operator departure
  2. Update the token in the agent’s runtime configuration and confirm the agent reconnects
  3. Treat the token as a secret with the same handling as any other production credential

Step 3: Delete Stale Agents

  1. Delete any agent that is no longer running, no longer owned, or no longer bound to an active connector
  2. Confirm the corresponding container workload is torn down in your environment, not merely deregistered

Step 4: Harden the Agent Host

  1. Run the agent on a dedicated, patched host or namespace with least-privilege network egress
  2. Apply your standard container hardening and monitoring to the agent workload

Validation & Testing

  • Confirm the registered-agent list in the dashboard matches your running workloads exactly
  • After a token regeneration, confirm the old token no longer authenticates
  • Confirm a deleted agent’s workload stops processing and its connectors report the expected failure

4. Monitoring & Compliance

4.1 Configure Activity Logging

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 8.2
NIST 800-53 AU-2

Description

Monitor user and connector activity.

Rationale

Why This Matters:

  • Activity logs provide the audit trail needed to detect unauthorized logins, permission changes, and connector tampering
  • Exporting logs to a SIEM enables correlation, alerting, and retention beyond the dashboard’s native view
  • Monitoring credential and SSO configuration changes catches attacker attempts to weaken authentication controls
  • Without logging, account compromise and configuration drift go undetected and forensic investigation is impossible

Attack Prevented: Undetected account compromise, configuration tampering, insider misuse, post-incident blind spots

ClickOps Implementation

Step 1: Access Activity Logs

  1. Navigate to: Account SettingsActivity Log
  2. Review logged events:
    • User logins
    • Configuration changes
    • Connector modifications
    • Sync activities

Step 2: Export Logs to an External Service

  1. Configure an external logging service on the destination. Fivetran supports AWS CloudWatch, Azure Monitor, Datadog, Dynatrace, Google Cloud Logging, Grafana Loki, New Relic Log, and Splunk
  2. Note the one-per-destination constraint: a destination can be connected to only one external logging service at a time, so pick the system that is actually your investigation surface rather than the one that is easiest to wire up
  3. Plan gate: external logging and the Audit Trail require an Enterprise or Business Critical plan
  4. If you are on a plan without external logging, use the Fivetran Platform Connector instead — it is available on all plans at no additional cost and lands log and metadata tables in your destination, which you can then query or forward to your SIEM
  5. Set retention and alerting on the receiving system, not just on Fivetran’s dashboard view

Step 3: Monitor Key Events

  1. User provisioning/deprovisioning
  2. SSO configuration changes
  3. Connector credential updates
  4. Permission modifications

Code Implementation

Code Pack: Terraform
hth-fivetran-4.01-configure-activity-logging.tf View source on GitHub ↗
# Configure webhook for streaming activity logs to SIEM/monitoring
# Fivetran emits events for user logins, config changes, connector mods, syncs
resource "fivetran_webhook" "activity_log_webhook" {
  count = var.webhook_url != "" ? 1 : 0

  type   = "account"
  url    = var.webhook_url
  secret = var.webhook_secret
  active = true

  events = [
    "sync_start",
    "sync_end",
    "status",
    "connection_successful",
    "connection_failure",
    "dbt_run_start",
    "dbt_run_succeeded",
    "dbt_run_failed"
  ]
}

# Audit: enumerate recent activity log events via API
resource "null_resource" "audit_activity_logs" {
  triggers = {
    timestamp = timestamp()
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "Activity Log Audit"
      echo "============================================="
      echo ""

      # Fetch recent activity log entries
      curl -s \
        "https://api.fivetran.com/v1/account/activity-log?limit=10" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
events = data.get('data', {}).get('items', [])
print(f'Recent activity log entries (last 10):')
print('')
for e in events:
    print(f'  [{e.get(\"created_at\", \"\")}] {e.get(\"event\", \"unknown\")} -- {e.get(\"actor\", \"system\")}')
if not events:
    print('  No activity log entries found (or API permissions insufficient)')
print('')
print('Key events to monitor:')
print('  - User logins and provisioning/deprovisioning')
print('  - SSO configuration changes')
print('  - Connector credential updates')
print('  - Permission modifications')
print('  - Sync failures and errors')
" 2>/dev/null || echo "Note: Python3 required for activity log report"
    EOT
  }
}

4.2 Configure Sync Monitoring

Profile Level: L1 (Crawl)

Framework Control
CIS Controls 8.2
NIST 800-53 CA-7

Description

Monitor data sync status and errors.

Rationale

Why This Matters:

  • Sync failure alerts surface broken or tampered pipelines quickly, protecting data freshness and integrity
  • Webhook integration with monitoring systems enables automated detection and response to abnormal sync behavior
  • Prompt investigation of errors distinguishes routine failures from credential revocation or malicious interference
  • Silent sync failures can mask data manipulation, exfiltration, or a compromised source connection

Attack Prevented: Undetected pipeline tampering, data integrity loss, silent connector compromise, delayed incident response

ClickOps Implementation

Step 1: Configure Notifications

  1. Navigate to: Notification Settings
  2. Enable sync failure alerts
  3. Configure email recipients

Step 2: Monitor Sync Health

  1. Review sync dashboard
  2. Identify failed syncs
  3. Investigate errors promptly

Step 3: Configure Webhooks

  1. Set up webhooks for events
  2. Integrate with monitoring systems
  3. Automate incident response

Code Implementation

Code Pack: Terraform
hth-fivetran-4.02-configure-sync-monitoring.tf View source on GitHub ↗
# Configure notification settings for sync failure alerts
# Integrates with email, Slack, PagerDuty, and custom webhooks
resource "fivetran_webhook" "sync_failure_webhook" {
  count = var.webhook_url != "" ? 1 : 0

  type   = "account"
  url    = var.webhook_url
  secret = var.webhook_secret
  active = true

  events = [
    "sync_end",
    "connection_failure",
    "status"
  ]
}

# Audit: check current sync health across all connectors
resource "null_resource" "audit_sync_health" {
  triggers = {
    timestamp = timestamp()
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "Checking sync health across all connectors..."
      curl -s \
        "https://api.fivetran.com/v1/groups/${var.fivetran_account_id}/connectors" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
connectors = data.get('data', {}).get('items', [])
failed = [c for c in connectors if c.get('status', {}).get('sync_state') == 'failure']
paused = [c for c in connectors if c.get('paused')]
healthy = len(connectors) - len(failed) - len(paused)
print(f'Connector Health Summary:')
print(f'  Total:   {len(connectors)}')
print(f'  Healthy: {healthy}')
print(f'  Failed:  {len(failed)}')
print(f'  Paused:  {len(paused)}')
if failed:
    print('')
    print('Failed connectors requiring attention:')
    for c in failed:
        print(f'  - {c.get(\"service\", \"unknown\")}: {c.get(\"schema\", \"\")}')
" 2>/dev/null || echo "Note: Python3 required for sync health report"
    EOT
  }
}

4.3 Data Governance

Profile Level: L2 (Walk)

Framework Control
CIS Controls 3.1
NIST 800-53 AC-3

Description

Implement data governance controls for sensitive data.

Rationale

Why This Matters:

  • Column blocking prevents sensitive fields such as PII from ever being replicated into the destination, reducing the data footprint
  • Column hashing protects sensitive values while preserving referential integrity for analytics
  • Documented data flows and lineage support compliance audits and rapid scoping during an incident
  • Replicating unnecessary sensitive data expands breach impact and regulatory exposure across every destination

Attack Prevented: PII over-exposure, sensitive-data sprawl, compliance violations, expanded breach blast radius

ClickOps Implementation

Step 1: Configure Column Blocking

  1. Navigate to connector settings
  2. Block sensitive columns from sync so they are never written to the destination
  3. Primary-key columns cannot be blocked or hashed — Fivetran needs them to identify and update rows. If a primary key is itself sensitive (an email address, a national ID), the fix is upstream schema design or a different sync strategy, not column blocking
  4. Column blocking and hashing apply to all connectors except Magic Folder
  5. Blocking a column does not reduce your MAR (monthly active rows). Treat column blocking as a privacy and data-minimization control, not a cost control — budgeting on the assumption that blocked columns are free will be wrong

Step 2: Configure Hashing

  1. Enable column hashing for sensitive columns you still need to join or count on
  2. Hashing is one-way — the original value cannot be recovered from the destination, so hash only what you will never need to read back
  3. Fivetran salts hashes per destination, so a hashed value is joinable across tables within one destination but not across two different destinations. Design cross-destination joins accordingly rather than discovering the mismatch in production

Step 3: Document Data Flows

  1. Inventory all connectors
  2. Document data destinations
  3. Maintain data lineage

Code Implementation

Code Pack: Terraform
hth-fivetran-4.03-data-governance.tf View source on GitHub ↗
# Data governance: column blocking and hashing for sensitive data (L2+)
# Prevents PII replication and maintains referential integrity

# Block sensitive columns from sync (L2+)
# Column blocking prevents specific columns from being replicated to the destination
resource "fivetran_connector_schema_config" "column_blocking" {
  for_each = var.profile_level >= 2 ? var.blocked_columns : {}

  connector_id          = each.key
  schema_change_handling = "BLOCK_ALL"

  # Note: Column-level blocking is configured per-schema within the connector.
  # The fivetran_connector_schema_config resource manages schema-level settings.
  # For column-level blocking, use the schema configuration to disable
  # specific columns containing PII or sensitive data.
  #
  # Blocked columns for this connector:
  # %{ for col in each.value ~}
  #   - ${col}
  # %{ endfor ~}
}

# Hash sensitive columns during sync (L2+)
# Hashing replaces column values with one-way hashes for referential integrity
resource "null_resource" "configure_column_hashing" {
  for_each = var.profile_level >= 2 ? var.hashed_columns : {}

  triggers = {
    connector_id = each.key
    columns      = join(",", each.value)
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "Column Hashing Configuration (L2+)"
      echo "============================================="
      echo ""
      echo "Connector: ${each.key}"
      echo "Columns to hash:"
      %{ for col in each.value ~}
      echo "  - ${col}"
      %{ endfor ~}
      echo ""
      echo "Column hashing is configured via Fivetran Dashboard:"
      echo "  1. Navigate to connector settings"
      echo "  2. Go to Schema tab"
      echo "  3. Select the column to hash"
      echo "  4. Enable 'Hash this column'"
      echo ""
      echo "Hashing preserves referential integrity while protecting PII."
      echo "Hashed values are consistent -- the same input always produces"
      echo "the same hash -- enabling joins across tables."
    EOT
  }
}

# Audit: document data flows for governance
resource "null_resource" "audit_data_flows" {
  count = var.profile_level >= 2 ? 1 : 0

  triggers = {
    profile_level = var.profile_level
    timestamp     = timestamp()
  }

  provisioner "local-exec" {
    command = <<-EOT
      echo "============================================="
      echo "Data Governance Audit (L2+)"
      echo "============================================="
      echo ""

      # Inventory all connectors and destinations
      curl -s \
        "https://api.fivetran.com/v1/groups" \
        -H "Authorization: Basic $(echo -n '${var.fivetran_api_key}:${var.fivetran_api_secret}' | base64)" \
        | python3 -c "
import sys, json
data = json.load(sys.stdin)
groups = data.get('data', {}).get('items', [])
print(f'Data Flow Inventory:')
print(f'  Groups (destinations): {len(groups)}')
for g in groups:
    print(f'  - {g.get(\"name\", \"unnamed\")} (ID: {g.get(\"id\", \"\")})')
print('')
print('Data Governance Checklist:')
print('  [1] Inventory all connectors and their data sources')
print('  [2] Document data destinations and schemas')
print('  [3] Block sensitive/PII columns from sync')
print('  [4] Hash columns requiring referential integrity')
print('  [5] Maintain data lineage documentation')
print('  [6] Review data flows quarterly')
" 2>/dev/null || echo "Note: Python3 required for data flow audit report"
    EOT
  }
}

5. Compliance Quick Reference

SOC 2 Trust Services Criteria Mapping

Control ID Fivetran Control Guide Section
CC6.1 SSO/SAML 1.1
CC6.2 RBAC 2.1
CC6.6 Session timeout 1.4
CC6.7 Encryption 3.3
CC7.2 Activity logging 4.1

NIST 800-53 Rev 5 Mapping

Control Fivetran Control Guide Section
IA-2 SSO 1.1
AC-2 SCIM provisioning 2.3
AC-6 Least privilege 2.1
SC-12 Credential security 3.1
IA-5 External secret management 3.4
CM-8 Hybrid Deployment agent inventory 3.5
AU-2 Audit logging 4.1

Appendix A: Plan Compatibility

Feature Standard Enterprise Business Critical
SAML SSO
Custom Session Timeout
SCIM Provisioning
Custom Roles
External Logging & Audit Trail
Fivetran Platform Connector
External Secrets Managers (private preview)
Private Networking Add-on Add-on
Advanced Security

Appendix B: References

Official Fivetran Documentation:

API & Developer Documentation:

Security Incidents:

  • No major public security incidents identified affecting the Fivetran platform.

Changelog

Date Version Maturity Changes Author
2026-08-08 0.2.0 draft Currency pass against Fivetran docs: corrected 2.3 (SCIM does NOT map IdP groups to teams/roles; IdP becomes the only user-management path), 1.1/1.3 (Single Sign-On page name, mandatory email NameID and RSA-SHA256 assertion signing), 1.2 (named Google OAuth as a third login path to close), 4.1 (real external logging destination list, one service per destination, Enterprise/Business Critical gate, all-plans Platform Connector alternative), 4.3 (primary keys cannot be blocked or hashed, one-way per-destination-salted hashing, blocking does not reduce MAR, Magic Folder exception), 3.2 (prefer hostname over IP allowlisting; IPs may change without notice), 2.1 (custom roles are Enterprise/Business Critical; role names softened pending a resolvable roles doc); added 3.4 External Secrets Managers (private preview) and 3.5 Hybrid Deployment agent governance; added missing Attack Prevented lines to 1.1 and 3.1; pruned Trust Center, /security marketing, compliance-badge, and whitepaper links from Appendix B and added the IP, logs, SCIM, secrets-manager, hybrid-agent, and column-blocking docs. Tier 2 survey found no CIS Benchmark, DISA STIG, or CISA SCuBA baseline for Fivetran; Tier 3/4 not surveyed this pass. Claude Code (Opus 4.8)
2025-02-05 0.1.0 draft Initial guide with SSO, access controls, and connector security Claude Code (Opus 4.5)

Contributing

Found an issue or want to improve this guide?