Skip to content

AWS Targets

SecretZero supports two AWS secret management services: AWS Secrets Manager and AWS Systems Manager Parameter Store. Both provide secure, scalable secret storage with native AWS integration.

Overview

AWS targets allow you to:

  • Store secrets in AWS cloud infrastructure
  • Leverage AWS KMS for encryption
  • Integrate with IAM for fine-grained access control
  • Enable automatic rotation with AWS Lambda
  • Audit access with AWS CloudTrail
  • Scale globally with multi-region support

Prerequisites

Installation

AWS support requires the boto3 library:

# Install with AWS support
pip install secretzero[aws]

# Or install boto3 directly
pip install boto3

Authentication

AWS targets use the standard AWS credential chain:

  1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  2. AWS credentials file (~/.aws/credentials)
  3. IAM instance profile (EC2, ECS, Lambda)
  4. IAM role (EKS, Fargate)
providers:
  aws:
    kind: aws
    auth:
      kind: ambient  # Uses AWS credential chain
      region: us-east-1

Required IAM Permissions

For Secrets Manager:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:CreateSecret",
        "secretsmanager:UpdateSecret",
        "secretsmanager:GetSecretValue",
        "secretsmanager:DeleteSecret",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:*:*:secret:*"
    }
  ]
}

For Parameter Store:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:PutParameter",
        "ssm:GetParameter",
        "ssm:DeleteParameter",
        "ssm:DescribeParameters"
      ],
      "Resource": "arn:aws:ssm:*:*:parameter/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt"
      ],
      "Resource": "arn:aws:kms:*:*:key/*"
    }
  ]
}

AWS Secrets Manager Target

AWS Secrets Manager is designed for secrets like database credentials, API keys, and OAuth tokens. It supports automatic rotation and integrates seamlessly with AWS services.

Configuration

targets:
  - provider: aws
    kind: secrets_manager
    config:
      name: string           # Secret name or ARN (required)
      description: string    # Secret description (optional)
      kms_key_id: string    # KMS key ARN/ID (optional)

Configuration Options

Option Type Required Default Description
name string Yes - Secret name or ARN
description string No "Managed by SecretZero: {secret_name}" Human-readable description
kms_key_id string No AWS managed key KMS key ARN or alias for encryption

Basic Example

version: '1.0'

providers:
  aws:
    kind: aws
    auth:
      kind: ambient
      region: us-east-1

secrets:
  - name: database_password
    kind: random_password
    config:
      length: 32
      special: true
      exclude_characters: '"@/\'
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: myapp/prod/db/password
          description: Production database password

Advanced Example with KMS

secrets:
  - name: api_key
    kind: random_string
    config:
      length: 32
      charset: alphanumeric
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: myapp/api-key
          description: External API key for service XYZ
          kms_key_id: arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012

Multi-Region Secrets

variables:
  regions:
    - us-east-1
    - us-west-2
    - eu-west-1

secrets:
  - name: global_api_key
    kind: random_string
    config:
      length: 32
    targets:
      # Deploy to multiple regions
      - provider: aws_us_east
        kind: secrets_manager
        config:
          name: global/api-key

      - provider: aws_us_west
        kind: secrets_manager
        config:
          name: global/api-key

      - provider: aws_eu_west
        kind: secrets_manager
        config:
          name: global/api-key

providers:
  aws_us_east:
    kind: aws
    auth:
      kind: ambient
      region: us-east-1

  aws_us_west:
    kind: aws
    auth:
      kind: ambient
      region: us-west-2

  aws_eu_west:
    kind: aws
    auth:
      kind: ambient
      region: eu-west-1

Structured Secrets

Store complex credentials as JSON:

secrets:
  - name: database_credentials
    kind: templates.db_config

templates:
  db_config:
    fields:
      host:
        generator:
          kind: static
          config:
            default: db.example.com
      port:
        generator:
          kind: static
          config:
            default: "5432"
      username:
        generator:
          kind: static
          config:
            default: app_user
      password:
        generator:
          kind: random_password
          config:
            length: 32
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: myapp/database/credentials

Retrieved as:

{
  "host": "db.example.com",
  "port": "5432",
  "username": "app_user",
  "password": "randompassword123456789012345678901"
}

AWS Systems Manager Parameter Store Target

Parameter Store is ideal for configuration data, feature flags, and secrets that don't require automatic rotation. It's cost-effective and integrates with AWS Systems Manager.

Configuration

targets:
  - provider: aws
    kind: ssm_parameter
    config:
      name: string         # Parameter name/path (required)
      type: string         # Parameter type (optional)
      overwrite: boolean   # Overwrite existing (optional)
      description: string  # Description (optional)
      tier: string        # Parameter tier (optional)

Configuration Options

Option Type Required Default Description
name string Yes - Parameter name/path (e.g., /myapp/db/password)
type string No SecureString Parameter type: String, SecureString, StringList
overwrite boolean No true Whether to overwrite existing parameters
description string No "Managed by SecretZero: {secret_name}" Parameter description
tier string No Standard Parameter tier: Standard, Advanced, Intelligent-Tiering

Parameter Types

  • String - Plain text parameter (not recommended for secrets)
  • SecureString - Encrypted with KMS (recommended for secrets)
  • StringList - Comma-separated values

Basic Example

version: '1.0'

providers:
  aws:
    kind: aws
    auth:
      kind: ambient
      region: us-east-1

secrets:
  - name: app_secret_key
    kind: random_string
    config:
      length: 64
      charset: base64
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/prod/secret-key
          type: SecureString
          overwrite: true
          tier: Standard

Hierarchical Organization

Use paths to organize parameters:

secrets:
  # Database parameters
  - name: db_password
    kind: random_password
    config:
      length: 32
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/prod/database/password
          type: SecureString

  - name: db_host
    kind: static
    config:
      value: prod-db.example.com
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/prod/database/host
          type: String

  # API parameters
  - name: api_key
    kind: random_string
    config:
      length: 32
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/prod/api/key
          type: SecureString

  # Application parameters
  - name: app_debug
    kind: static
    config:
      value: "false"
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/prod/app/debug
          type: String

Advanced Tier Usage

Use Advanced tier for larger values:

secrets:
  - name: large_certificate
    kind: static
    config:
      value: |
        -----BEGIN CERTIFICATE-----
        MIIEpQIBAAKCAQEA...
        (large certificate content)
        -----END CERTIFICATE-----
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /myapp/certificates/app-cert
          type: SecureString
          tier: Advanced  # Supports up to 8KB

Tier Limits: - Standard: 4 KB, free - Advanced: 8 KB, charges apply - Intelligent-Tiering: Automatically switches based on size

Environment-Based Parameters

variables:
  environment: prod
  app_name: myapp

secrets:
  - name: secret_key
    kind: random_string
    config:
      length: 64
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /{{var.app_name}}/{{var.environment}}/secret-key
          type: SecureString
          description: "Secret key for {{var.app_name}} {{var.environment}}"

Comparison: Secrets Manager vs. Parameter Store

Feature Secrets Manager Parameter Store (SecureString)
Encryption KMS (required) KMS (optional)
Automatic Rotation Yes (built-in) No (manual via Lambda)
Cross-Region Replication Yes No
Versioning Yes (automatic) Yes (manual)
Max Size 65,536 bytes 4 KB (Standard), 8 KB (Advanced)
Cost $0.40/secret/month + API calls Free (Standard), $0.05/param/month (Advanced)
Use Case Sensitive credentials, rotating secrets Configuration, non-rotating secrets
AWS Service Integration RDS, DocumentDB, Redshift EC2, ECS, Lambda, Systems Manager

When to Use Each

Use Secrets Manager when: - Secrets require automatic rotation - Managing database credentials - Need cross-region replication - Want built-in integration with RDS/DocumentDB - Compliance requires secret rotation

Use Parameter Store when: - Storing configuration values - Managing application settings - Need hierarchical organization - Cost is a primary concern - Secrets don't require rotation

Complete Examples

Multi-Tier Application

version: '1.0'

variables:
  environment: production
  app_name: webapp

providers:
  aws:
    kind: aws
    auth:
      kind: ambient
      region: us-east-1

secrets:
  # Critical secrets → Secrets Manager
  - name: database_master_password
    kind: random_password
    config:
      length: 32
      special: true
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: "{{var.app_name}}/{{var.environment}}/db/master-password"
          description: Master database password

  - name: jwt_signing_key
    kind: random_string
    config:
      length: 64
      charset: base64
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: "{{var.app_name}}/{{var.environment}}/jwt/signing-key"

  # Configuration → Parameter Store
  - name: db_connection_pool_size
    kind: static
    config:
      value: "20"
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /{{var.app_name}}/{{var.environment}}/db/pool-size
          type: String

  - name: log_level
    kind: static
    config:
      value: INFO
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /{{var.app_name}}/{{var.environment}}/logging/level
          type: String

  - name: feature_flag_new_ui
    kind: static
    config:
      value: "true"
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /{{var.app_name}}/{{var.environment}}/features/new-ui
          type: String

Microservices Architecture

version: '1.0'

providers:
  aws:
    kind: aws
    auth:
      kind: ambient
      region: us-east-1

secrets:
  # Shared secrets
  - name: shared_encryption_key
    kind: random_string
    config:
      length: 64
      charset: hex
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: shared/encryption-key

  # Service-specific secrets
  - name: auth_service_db_password
    kind: random_password
    config:
      length: 32
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /services/auth/db/password
          type: SecureString

  - name: payment_service_api_key
    kind: random_string
    config:
      length: 32
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: services/payment/api-key

  - name: notification_service_smtp_password
    kind: random_password
    config:
      length: 24
    targets:
      - provider: aws
        kind: ssm_parameter
        config:
          name: /services/notification/smtp/password
          type: SecureString

Best Practices

1. Use Consistent Naming Conventions

# Good: hierarchical structure
/myapp/prod/database/password
/myapp/prod/api/key
/myapp/staging/database/password

# Avoid: inconsistent naming
myapp-db-pass
MYAPP_API_KEY
app.secret

2. Leverage Tags for Organization

# Note: Tagging requires AWS API calls beyond SecretZero
# Use external tools or scripts to add tags:

# AWS CLI example:
# aws secretsmanager tag-resource \
#   --secret-id myapp/api-key \
#   --tags Key=Environment,Value=production Key=Owner,Value=platform-team

3. Enable CloudTrail Logging

Monitor secret access:

# Enable CloudTrail for Secrets Manager
aws cloudtrail create-trail \
  --name secrets-audit \
  --s3-bucket-name my-audit-bucket

# Enable logging
aws cloudtrail start-logging --name secrets-audit

4. Use Least Privilege IAM

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:myapp/prod/*"
    }
  ]
}

5. Implement Secret Rotation

# Generate rotatable secrets
secrets:
  - name: db_password
    kind: random_password
    rotation_period: 90d  # Rotate every 90 days
    config:
      length: 32
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: myapp/db/password

Troubleshooting

Access Denied Errors

Problem: AccessDeniedException when storing/retrieving secrets.

Solutions: 1. Verify IAM permissions

aws secretsmanager get-secret-value --secret-id test-secret
2. Check resource-based policies 3. Ensure KMS key permissions if using custom keys

Secret Already Exists

Problem: ResourceExistsException when creating secrets.

Solution: SecretZero automatically updates existing secrets. If you see this error: 1. Verify the secret name is correct 2. Check if another process is creating secrets 3. Use overwrite: true for Parameter Store

KMS Key Not Found

Problem: KMSKeyNotFoundException when using custom KMS keys.

Solutions: 1. Verify KMS key ARN/alias is correct 2. Ensure KMS key is in the same region 3. Check KMS key permissions:

aws kms describe-key --key-id <key-arn>

Parameter Size Exceeded

Problem: ParameterMaxLength error for Parameter Store.

Solutions: 1. Use Advanced tier for larger parameters:

config:
  tier: Advanced
2. Switch to Secrets Manager (65KB limit) 3. Split large values into multiple parameters

Security Considerations

Encryption

Both services encrypt secrets at rest:

  • Secrets Manager: Mandatory KMS encryption
  • Parameter Store SecureString: KMS encryption (AWS managed or custom key)
# Use custom KMS key
secrets:
  - name: sensitive_key
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: sensitive-key
          kms_key_id: alias/myapp-secrets

Access Control

Use IAM policies and resource tags:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "secretsmanager:GetSecretValue",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "secretsmanager:ResourceTag/Environment": "production"
        }
      }
    }
  ]
}

Audit Logging

Enable CloudTrail for complete audit trail:

  • Secret creation/updates
  • Secret access (GetSecretValue, GetParameter)
  • Secret deletion
  • KMS key usage

Secret Deletion

# Secrets Manager: 7-30 day recovery window
# Force immediate deletion in code (use with caution):
# sm.delete_secret(SecretId=secret_id, ForceDeleteWithoutRecovery=True)

# Parameter Store: Immediate deletion
# No recovery period

AWS Service Integration

ECS Task Definitions

{
  "containerDefinitions": [
    {
      "name": "app",
      "secrets": [
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:myapp/db/password"
        },
        {
          "name": "API_KEY",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/api-key"
        }
      ]
    }
  ]
}

Lambda Functions

import boto3
import json

# Secrets Manager
secrets_client = boto3.client('secretsmanager')
response = secrets_client.get_secret_value(SecretId='myapp/db/password')
secret = json.loads(response['SecretString'])

# Parameter Store
ssm_client = boto3.client('ssm')
response = ssm_client.get_parameter(Name='/myapp/api-key', WithDecryption=True)
api_key = response['Parameter']['Value']

RDS Integration

# Create RDS master password
secrets:
  - name: rds_master_password
    kind: random_password
    config:
      length: 32
      special: true
      exclude_characters: '"@/\`'
    targets:
      - provider: aws
        kind: secrets_manager
        config:
          name: rds/master-password

Then reference in RDS:

aws rds create-db-instance \
  --db-instance-identifier mydb \
  --manage-master-user-password \
  --master-username admin \
  --engine postgres

Next Steps