Skip to content

Secrets Manager

Protocol: JSON 1.1 (X-Amz-Target: secretsmanager.*) Endpoint: POST http://localhost:4566/

Supported Actions

Action Description
CreateSecret Create a new secret
GetSecretValue Retrieve the current secret value
PutSecretValue Update the secret value (new version)
UpdateSecret Update secret metadata or value
DescribeSecret Get secret metadata and version info
ListSecrets List all secrets
DeleteSecret Delete a secret (with recovery window)
RestoreSecret Cancel a scheduled deletion and restore the secret
RotateSecret Trigger secret rotation, via a Lambda or by the owning service
CancelRotateSecret Turn off automatic rotation and report any half-staged AWSPENDING version
TagResource Tag a secret
UntagResource Remove tags
ListSecretVersionIds List all versions of a secret
GetResourcePolicy Get the resource policy
GetRandomPassword Generate a random password
BatchGetSecretValue Retrieve multiple secret values in one call
DeleteResourcePolicy Remove the resource policy
PutResourcePolicy Attach a resource policy
UpdateSecretVersionStage Move a staging label between versions
ValidateResourcePolicy Check a resource policy for overly broad principals
ReplicateSecretToRegions Replicate a secret into other regions
RemoveRegionsFromReplication Delete replicas from the given regions
StopReplicationToReplica Promote a replica to a standalone primary

Configuration

Variable Default Description
FLOCI_SERVICES_SECRETSMANAGER_ENABLED true Enable or disable the service
FLOCI_SERVICES_SECRETSMANAGER_DEFAULT_RECOVERY_WINDOW_DAYS 30 Days before a deleted secret is permanently purged
FLOCI_SERVICES_SECRETSMANAGER_SCHEDULED_ROTATION_ENABLED true Run the background sweep that fires rotations when a schedule comes due
FLOCI_SERVICES_SECRETSMANAGER_ROTATION_TICK_SECONDS 60 How often that sweep looks for due rotations

Examples

export AWS_ENDPOINT_URL=http://localhost:4566

# Create a string secret
aws secretsmanager create-secret \
  --name /app/database-url \
  --secret-string "postgresql://admin:secret@localhost/mydb" \
  --endpoint-url $AWS_ENDPOINT_URL

# Create a JSON secret
aws secretsmanager create-secret \
  --name /app/api-keys \
  --secret-string '{"stripe":"sk_test_xxx","sendgrid":"SG.xxx"}' \
  --endpoint-url $AWS_ENDPOINT_URL

# Retrieve a secret
aws secretsmanager get-secret-value \
  --secret-id /app/database-url \
  --endpoint-url $AWS_ENDPOINT_URL

# Update a secret
aws secretsmanager put-secret-value \
  --secret-id /app/database-url \
  --secret-string "postgresql://admin:new-password@localhost/mydb" \
  --endpoint-url $AWS_ENDPOINT_URL

# List secrets
aws secretsmanager list-secrets --endpoint-url $AWS_ENDPOINT_URL

# Delete (with recovery window)
aws secretsmanager delete-secret \
  --secret-id /app/database-url \
  --recovery-window-in-days 7 \
  --endpoint-url $AWS_ENDPOINT_URL

# Delete immediately (no recovery)
aws secretsmanager delete-secret \
  --secret-id /app/database-url \
  --force-delete-without-recovery \
  --endpoint-url $AWS_ENDPOINT_URL

# Generate a random password
aws secretsmanager get-random-password \
  --password-length 24 \
  --exclude-punctuation \
  --endpoint-url $AWS_ENDPOINT_URL

# Batch-fetch multiple secrets in one call
aws secretsmanager batch-get-secret-value \
  --secret-id-list /app/database-url /app/api-keys \
  --endpoint-url $AWS_ENDPOINT_URL

# Move the AWSCURRENT label to a different version (e.g. during a rotation)
aws secretsmanager update-secret-version-stage \
  --secret-id /app/database-url \
  --version-stage AWSCURRENT \
  --move-to-version-id <new-version-id> \
  --remove-from-version-id <old-version-id> \
  --endpoint-url $AWS_ENDPOINT_URL

# Turn on scheduled rotation, then turn it back off
aws secretsmanager rotate-secret \
  --secret-id /app/database-url \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:000000000000:function:my-rotator \
  --rotation-rules '{"ScheduleExpression":"rate(10 days)"}' \
  --endpoint-url $AWS_ENDPOINT_URL

aws secretsmanager cancel-rotate-secret \
  --secret-id /app/database-url \
  --endpoint-url $AWS_ENDPOINT_URL

# Replicate to another region, then promote the replica to its own primary
aws secretsmanager replicate-secret-to-regions \
  --secret-id /app/database-url \
  --add-replica-regions Region=eu-west-1 \
  --endpoint-url $AWS_ENDPOINT_URL

aws secretsmanager stop-replication-to-replica \
  --secret-id /app/database-url \
  --region eu-west-1 \
  --endpoint-url $AWS_ENDPOINT_URL

# Check a resource policy before attaching it
aws secretsmanager validate-resource-policy \
  --secret-id /app/database-url \
  --resource-policy file://policy.json \
  --endpoint-url $AWS_ENDPOINT_URL

Behaviour notes

  • Rotation schedules fire. A background sweep (see the config table) rotates any secret whose NextRotationDate has passed. AutomaticallyAfterDays, rate() and cron() are all honoured.
  • RotateSecret also needs lambda:InvokeFunction under IAM enforcement. As on AWS, the caller must be allowed to invoke the rotation function as well as to call RotateSecret. A caller that is not gets AccessDeniedException with HTTP 400, as Secrets Manager reports it, and the secret is left as it was. Rotations started by the background sweep have no caller and are not checked.
  • A rotation function that does not exist is reported as AWS reports it: AccessDeniedException (HTTP 400), "Secrets Manager cannot invoke the specified Lambda function". The secret's rotation settings are left as they were, including any rotation function configured before.
  • A rotation function reference Lambda refuses, one it cannot parse or a full ARN in another Region, gets InvalidParameterException (HTTP 400), the error RotateSecret declares for an invalid parameter, with Lambda's reason in the message. The secret is left as it was. AWS does not document which error a function in another Region gets.
  • Replication is synchronous. Real AWS reports InProgress first; floci copies the secret immediately, so a replica is InSync by the time the call returns. Replicas are read-only and track later writes to the primary.
  • Secret values are stored in the clear. KmsKeyId is validated — a missing key is rejected, and a disabled or pending-deletion key raises EncryptionFailure — but values are not actually encrypted, since encrypting with the emulator's own KMS would protect nothing.
  • ValidateResourcePolicy and BlockPublicPolicy check for wildcard principals only. AWS runs the policy through Zelkova; a pass here is weaker than a pass on AWS. PutResourcePolicy with BlockPublicPolicy raises PublicPolicyException for a wildcard principal, and — as on AWS — leaves such a policy alone when the flag is absent.
  • PrimaryRegion and ReplicationStatus appear only on multi-region secrets, matching AWS's "only returns fields that have a value" rule — a standalone secret carries neither.
  • Rotation schedule limits are enforced: AutomaticallyAfterDays 1–1000, Duration as Nh, and rate() in hours or days no faster than every four hours.
  • Known deviation: RotateSecret with RotateImmediately: false invokes the rotation function's testSecret step but does not first create the throwaway AWSPENDING version that AWS creates and removes, so a rotation function whose testSecret reads that version by id will not find it.