v0.1.0-draft AI Drafted

Stripe Hardening Guide

Productivity Last updated: 2025-02-05

Payment platform hardening for Stripe including SSO configuration, team permissions, and API key security

Overview

Stripe is a leading payment processing platform serving millions of businesses for online transactions. As a platform handling sensitive payment data, Stripe security configurations directly impact PCI compliance and financial data protection.

Intended Audience

  • Security engineers managing payment platforms
  • IT administrators configuring Stripe
  • Finance teams managing payment processing
  • GRC professionals assessing payment security

How to Use This Guide

  • L1 (Baseline): Essential controls for all organizations
  • L2 (Hardened): Enhanced controls for security-sensitive environments
  • L3 (Maximum Security): Strictest controls for regulated industries

Scope

This guide covers Stripe Dashboard security including SSO, team permissions, API key management, and webhook security.


Table of Contents

  1. Authentication & SSO
  2. Access Controls
  3. API Security
  4. Compliance Quick Reference

1. Authentication & SSO

1.1 Configure SAML Single Sign-On

Profile Level: L1 (Baseline)

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

Description

Configure SAML SSO for Stripe Dashboard access.

Prerequisites

  • Stripe account with SSO support
  • Account owner access
  • SAML 2.0 compatible IdP

ClickOps Implementation

Step 1: Access SSO Settings

  1. Navigate to: DashboardSettingsTeam and security
  2. Find Single Sign-On section

Step 2: Configure SAML

  1. Enable SAML SSO
  2. Configure IdP settings:
    • SSO URL
    • Entity ID
    • Certificate
  3. Download Stripe metadata for IdP

Step 3: Test and Enforce

  1. Test SSO authentication
  2. Enable SSO enforcement
  3. Configure admin fallback

Time to Complete: ~1-2 hours


1.2 Enforce Two-Factor Authentication

Profile Level: L1 (Baseline)

Framework Control
CIS Controls 6.5
NIST 800-53 IA-2(1)

Description

Require 2FA for all Stripe team members.

ClickOps Implementation

Step 1: Enable 2FA Requirement

  1. Navigate to: SettingsTeam and security
  2. Enable Require two-step authentication
  3. All team members must configure 2FA

Step 2: Configure Methods

  1. Support authenticator apps
  2. Support SMS (backup)
  3. Use hardware keys for admins

1.3 Configure Session Security

Profile Level: L1 (Baseline)

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

Description

Configure session timeout settings.

ClickOps Implementation

Step 1: Configure Timeout

  1. Navigate to: SettingsTeam and security
  2. Configure session timeout
  3. Enable automatic logout

2. Access Controls

2.1 Configure Team Roles

Profile Level: L1 (Baseline)

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

Description

Implement least privilege using Stripe roles.

ClickOps Implementation

Step 1: Review Roles

  1. Navigate to: SettingsTeam
  2. Review available roles:
    • Administrator
    • Developer
    • Analyst
    • Support specialist
    • View only
  3. Assign minimum necessary role

Step 2: Apply Least Privilege

  1. Use View only for read access
  2. Limit Administrator access
  3. Regular access reviews

2.2 Limit Admin Access

Profile Level: L1 (Baseline)

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

Description

Minimize and protect administrator accounts.

ClickOps Implementation

Step 1: Inventory Admins

  1. Review administrator accounts
  2. Document admin access
  3. Identify unnecessary privileges

Step 2: Apply Restrictions

  1. Limit admins to 2-3 users
  2. Require 2FA for admins
  3. Monitor admin activity

3. API Security

3.1 Configure API Key Security

Profile Level: L1 (Baseline)

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

Description

Secure Stripe API keys.

ClickOps Implementation

Step 1: Review API Keys

  1. Navigate to: DevelopersAPI keys
  2. Review all API keys
  3. Document key purposes

Step 2: Apply Best Practices

  1. Use restricted keys with minimum permissions
  2. Never expose secret keys
  3. Use test keys for development

Step 3: Key Rotation

  1. Rotate keys regularly
  2. Roll keys if compromised
  3. Update integrations

Code Pack: API Script
hth-stripe-3.01-configure-api-key-security.sh View source on GitHub ↗
# Monitor for account changes that may indicate key-related activity
# NOTE: Stripe has NO api_key.* event types — use account.updated instead
EVENTS=$(stripe_get "/events?type=account.updated&limit=10") || {
  fail "3.1 Unable to retrieve account events"
  increment_failed; summary; exit 0
}

EVENT_COUNT=$(echo "${EVENTS}" | jq '.data | length')
info "3.1 Recent account update events: ${EVENT_COUNT}"

if [ "${EVENT_COUNT}" -gt 0 ]; then
  info "3.1 Most recent account changes:"
  echo "${EVENTS}" | jq -r '.data[:5][] | "  - \(.created | todate): \(.type)"'
fi

pass "3.1 Account events audit complete — review API keys in Dashboard"
increment_applied
Code Pack: Sigma Detection Rule
hth-stripe-3.01-configure-api-key-security.yml View source on GitHub ↗
detection:
    selection:
        type: 'account.updated'
    condition: selection
fields:
    - id
    - created
    - type
    - data.object.id
    - data.previous_attributes

3.2 Configure Webhook Security

Profile Level: L2 (Hardened)

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

Description

Secure webhook endpoints.

ClickOps Implementation

Step 1: Configure Webhooks

  1. Navigate to: DevelopersWebhooks
  2. Review webhook endpoints
  3. Verify endpoint security

Step 2: Verify Signatures

  1. Always verify webhook signatures
  2. Use webhook secrets securely
  3. Reject unverified events

Code Pack: API Script
hth-stripe-3.02-configure-webhook-security.sh View source on GitHub ↗
# List existing webhooks and check for unsigned endpoints
WEBHOOKS=$(stripe_get "/webhook_endpoints?limit=100") || {
  fail "3.2 Unable to retrieve webhook endpoints"
  increment_failed; summary; exit 0
}

TOTAL=$(echo "${WEBHOOKS}" | jq '.data | length')
DISABLED=$(echo "${WEBHOOKS}" | jq '[.data[] | select(.status == "disabled")] | length')
info "3.2 Total webhook endpoints: ${TOTAL}"
info "3.2 Disabled endpoints: ${DISABLED}"

if [ "${DISABLED}" -gt 0 ]; then
  warn "3.2 Disabled webhook endpoints found — review and remove unused:"
  echo "${WEBHOOKS}" | jq -r '.data[] | select(.status == "disabled") | "  - \(.url) (id: \(.id))"'
fi

# Create a SIEM webhook for security events if URL is provided
if [ -n "${STRIPE_SIEM_WEBHOOK_URL:-}" ]; then
  EXISTING=$(echo "${WEBHOOKS}" | jq -r ".data[] | select(.url == \"${STRIPE_SIEM_WEBHOOK_URL}\") | .id")
  if [ -n "${EXISTING}" ]; then
    info "3.2 SIEM webhook already exists (id: ${EXISTING})"
  else
    info "3.2 Creating SIEM webhook for security events..."
    RESPONSE=$(stripe_post "/webhook_endpoints" "$(cat <<'PARAMS'
url=${STRIPE_SIEM_WEBHOOK_URL}&\
enabled_events[]=account.updated&\
enabled_events[]=account.application.authorized&\
enabled_events[]=account.application.deauthorized&\
enabled_events[]=account.external_account.created&\
enabled_events[]=account.external_account.deleted&\
enabled_events[]=person.created&\
enabled_events[]=person.updated&\
enabled_events[]=person.deleted&\
enabled_events[]=payment_method.attached&\
enabled_events[]=payment_method.detached&\
enabled_events[]=identity.verification_session.created&\
enabled_events[]=identity.verification_session.verified&\
enabled_events[]=capability.updated&\
description=HTH Security Events SIEM Webhook
PARAMS
    )") || {
      fail "3.2 Failed to create SIEM webhook"
      increment_failed; summary; exit 0
    }
    WEBHOOK_ID=$(echo "${RESPONSE}" | jq -r '.id')
    WEBHOOK_SECRET=$(echo "${RESPONSE}" | jq -r '.secret')
    pass "3.2 SIEM webhook created (id: ${WEBHOOK_ID})"
    info "3.2 Webhook signing secret: ${WEBHOOK_SECRET}"
    info "3.2 IMPORTANT: Store this secret securely for signature verification"
  fi
fi

pass "3.2 Webhook security audit complete"
increment_applied
Code Pack: Sigma Detection Rule
hth-stripe-3.02-configure-webhook-security.yml View source on GitHub ↗
detection:
    selection:
        request_method: 'DELETE'
        request_path|startswith: '/v1/webhook_endpoints/'
    condition: selection
fields:
    - timestamp
    - request_method
    - request_path
    - source_ip
    - api_key_id

3.3 Configure Restricted Keys

Profile Level: L2 (Hardened)

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

Description

Use restricted API keys for specific functions.

ClickOps Implementation

Step 1: Create Restricted Keys

  1. Navigate to: DevelopersAPI keys
  2. Create restricted key
  3. Select minimum permissions

Step 2: Apply Per-Integration

  1. Use separate keys per integration
  2. Document key purposes
  3. Audit key usage

Code Pack: API Script
hth-stripe-3.03-configure-restricted-keys.sh View source on GitHub ↗
# Test if the current key has overly broad permissions
# A restricted key should fail on resources it doesn't need
info "3.3 Testing key permissions scope..."

# Try to list customers (should fail if key is properly restricted)
if stripe_get "/customers?limit=1" > /dev/null 2>&1; then
  warn "3.3 Current key can list customers — may be overly permissive"
else
  pass "3.3 Current key cannot list customers — properly scoped"
fi

# Try to list payment intents
if stripe_get "/payment_intents?limit=1" > /dev/null 2>&1; then
  warn "3.3 Current key can list payment intents — review if needed"
else
  pass "3.3 Current key cannot list payment intents — properly scoped"
fi

# Try to list webhook endpoints (meta-permission check)
if stripe_get "/webhook_endpoints?limit=1" > /dev/null 2>&1; then
  info "3.3 Current key has webhook read access"
else
  info "3.3 Current key cannot list webhooks"
fi

pass "3.3 Key scope validation complete"
increment_applied

4. Compliance Quick Reference

SOC 2 Trust Services Criteria Mapping

Control ID Stripe Control Guide Section
CC6.1 SSO/2FA 1.1
CC6.2 Team roles 2.1
CC6.7 API key security 3.1

PCI DSS v4.0 Mapping

Requirement Stripe Control Guide Section
7 Team roles 2.1
8 Authentication 1.1

Appendix A: References

Official Stripe Documentation:

API & Developer Tools:

Compliance Frameworks:

Security Incidents:

  • (2024) Evolve Bank & Trust (a Stripe banking partner) was breached by LockBit ransomware. Customer data from Stripe and other fintechs may have been exposed, including names, SSNs, and bank account numbers. This was not a direct Stripe platform breach.
  • (2024-2025) Web skimming campaign exploited legacy Stripe API endpoints to validate stolen credit card data across approximately 49 merchant sites. Stripe infrastructure was not compromised.

Changelog

Date Version Maturity Changes Author
2025-02-05 0.1.0 draft Initial guide with SSO and API security Claude Code (Opus 4.5)

Contributing

Found an issue or want to improve this guide?