Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Encrypt Data with AWS KMS: Keys, Policies, Rotation

By Kokil Thapa | Last reviewed: August 2026

You need to encrypt data with AWS KMS: Keys, Policies, Rotation because storing plaintext secrets or PII in databases is a liability that no amount of firewall rules can fix. For developers building compliance-sensitive applications like legal-tech portals or fintech platforms, AWS Key Management Service provides the cryptographic backbone required to meet regulatory standards without managing physical HSMs. This guide covers the practical implementation of customer-managed keys, least-privilege policies, and automated rotation schedules specifically for PHP and Laravel workloads running on AWS infrastructure.

How Do You Choose Between Symmetric and Asymmetric Keys When You Encrypt Data with AWS KMS?

Selecting the correct key type is the first architectural decision you make when you secure sensitive application data. AWS KMS supports both symmetric and asymmetric keys, but they serve fundamentally different purposes in a production web environment.

Symmetric keys (AES-256-GCM) are the default choice for application-level encryption. They use a single key for both encryption and decryption, making them ideal for database field encryption, file storage protection, and envelope encryption patterns. In my experience building legal-tech portals where client documents must be encrypted at rest, symmetric CMKs provide the performance characteristics needed for high-throughput Laravel applications. The AWS SDK handles the cryptographic operations efficiently, and the cost per API call remains predictable.

Asymmetric keys (RSA or ECC) serve specific use cases: digital signatures, certificate signing, or encrypting data outside AWS that only specific parties can decrypt. They are computationally expensive and rarely appropriate for general application data encryption. Unless you have a documented requirement for non-repudiation or external party verification, stick with symmetric keys.

Key Type Decision FlowData Encryption Need?App Data / DB FieldsFile Storage / EnvelopeDigital SignaturesExternal Party ExchangeSYMMETRIC KEYASYMMETRIC KEYAES-256-GCM • High PerformanceAuto-Rotation SupportedRSA/ECC • Specialized UseManual Rotation Only
Choosing between symmetric and asymmetric keys when you encrypt data with AWS KMS depends entirely on your use case

Creating a Customer Managed Symmetric Key

AWS managed keys work for basic services, but any serious application requires Customer Managed Keys (CMKs) for auditability and policy control. Create one via CLI:

aws kms create-key \
  --key-usage ENCRYPT_DECRYPT \
  --key-spec SYMMETRIC_DEFAULT \
  --description "Production app data encryption key" \
  --tags TagKey=Environment,TagValue=Production \
  --region ap-south-1

Record the returned KeyId and ARN immediately. Store these in your application configuration or Secrets Manager — never hardcode them in source files. On projects I've maintained across multiple environments, tagging keys by environment prevents catastrophic cross-environment access during deployments.

What Is Envelope Encryption and Why Does It Matter When You Encrypt Data with AWS KMS?

Envelope encryption is the pattern that makes AWS KMS viable for application data at scale. Instead of calling KMS for every record you encrypt (which would hit rate limits and destroy performance), you generate a unique data key locally, use it to encrypt your payload, then encrypt only that small data key with KMS.

This approach gives you three critical advantages:

  • Performance: Bulk encryption happens locally using fast AES libraries; KMS calls occur only once per data key lifecycle
  • Cost control: KMS API charges stay minimal regardless of data volume
  • Security isolation: Compromising the encrypted data alone is useless without the KMS-protected data key
Envelope Encryption Workflow1. GenerateData Key2. EncryptPlaintext Locally3. WrapData Key via KMSPlaintext Data Key(Ephemeral)Encrypted Payload(Stored in DB/S3)Encrypted Data Key(Stored with Payload)Decryption: Unwrap Data Key via KMS → Decrypt Payload LocallyPlaintext key never persists • Single KMS call per operation
Envelope encryption separates bulk data protection from key management when you encrypt data with AWS KMS

Implementing Envelope Encryption in Laravel

The AWS SDK for PHP v3.x integrates cleanly with Laravel 12. Install via Composer and configure credentials through IAM roles (never static keys in .env):

composer require aws/aws-sdk-php-laravel

// In a dedicated EncryptionService
use Aws\Kms\KmsClient;
use Illuminate\Support\Facades\Storage;

class DocumentEncryptionService
{
    public function encryptDocument(string $plaintext, string $keyId): array
    {
        $kms = app(KmsClient::class);
        
        // Step 1: Generate data key
        $result = $kms->generateDataKey([
            'KeyId' => $keyId,
            'KeySpec' => 'AES_256',
        ]);
        
        // Step 2: Encrypt locally using OpenSSL
        $iv = random_bytes(12); // GCM nonce
        $ciphertext = openssl_encrypt(
            $plaintext,
            'aes-256-gcm',
            $result['Plaintext'],
            OPENSSL_RAW_DATA,
            $iv,
            $tag
        );
        
        // Step 3: Return bundle (encrypted key + iv + tag + ciphertext)
        return [
            'encrypted_key' => base64_encode($result['CiphertextBlob']),
            'iv' => base64_encode($iv),
            'tag' => base64_encode($tag),
            'ciphertext' => base64_encode($ciphertext),
        ];
    }
}

This pattern keeps KMS calls minimal while maintaining strong cryptographic guarantees. The plaintext data key exists only in memory during the operation and is never written to disk or logs.

How Do You Write Least-Privilege Key Policies When You Encrypt Data with AWS KMS?

Key policies are the primary authorization mechanism for CMKs. Unlike IAM policies which attach to users/roles, key policies attach directly to the key resource itself. Both must permit an action for it to succeed. This dual-control model is what makes KMS secure, but misconfiguring it is the most common failure mode I encounter during security audits.

A properly scoped key policy follows these principles:

  1. Always include the root account principal — removing it locks everyone out permanently, including AWS support
  2. Restrict to specific IAM roles — never grant wildcard principals except for the root account entry
  3. Limit actions to what's needed — application roles typically need only kms:Encrypt, kms:Decrypt, kms:GenerateDataKey
  4. Add condition keys for context — restrict by VPC endpoint, source IP, or request tags to prevent lateral movement

Production-Ready Key Policy Template

{
    "Version": "2012-10-17",
    "Id": "app-data-key-policy",
    "Statement": [
        {
            "Sid": "EnableRootAccountAccess",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "AllowApplicationEncryption",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::123456789012:role/LaravelAppRole"},
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:GenerateDataKey",
                "kms:DescribeKey"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "secretsmanager.ap-south-1.amazonaws.com"
                }
            }
        },
        {
            "Sid": "AllowAdminManagement",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::123456789012:role/DevOpsAdminRole"},
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        }
    ]
}

The kms:ViaService condition is particularly valuable. It ensures the key can only be used through specific AWS services, preventing direct API misuse even if credentials are compromised. For applications accessing S3 encrypted objects, add s3.ap-south-1.amazonaws.com to this list.

Common Policy Mistakes That Break Production

I've debugged several incidents caused by policy errors. Watch for these:

  • Missing DescribeKey permission — many SDKs call this before encryption; omitting it causes silent failures
  • Wrong region in ViaService — the service endpoint must match the key's region exactly
  • Overly broad wildcardskms:* on non-admin roles defeats the purpose of CMKs
  • Forgetting cross-account access — if Lambda in Account B needs to decrypt data encrypted by Account A, both the key policy AND Account B's IAM policy must allow it

How Does Automatic Key Rotation Work When You Encrypt Data with AWS KMS?

Automatic rotation is one of KMS's strongest compliance features, but understanding its mechanics prevents dangerous assumptions. For symmetric CMKs, AWS generates new backing key material annually while preserving the same key ID and ARN. Your application code requires zero changes.

Automatic Key Rotation TimelineKey ID: mrk-abc123... (Never Changes)Year 1Backing Key v1Year 2Backing Key v2Year 3Backing Key v3Year 4Backing Key v4✓ What Rotates Automatically• Backing key material (annually)• All old versions retained for decryption• Zero application code changes needed✗ What Does NOT Rotate• Key ID / ARN (permanent)• Key policies or aliases• Asymmetric or HMAC keys
Understanding what rotates automatically prevents mistakes when you encrypt data with AWS KMS in long-lived applications

Critical Rotation Constraints

Not all keys support automatic rotation. Know the boundaries:

Key TypeAuto-RotationManual Rotation MethodNotes
Symmetric CMK✅ AnnualN/ADefault for most app encryption
Multi-Region Symmetric✅ AnnualN/AAll replicas rotate together
Asymmetric RSA/ECC❌ NeverCreate new key + migrateRequires application reconfiguration
HMAC Keys❌ NeverCreate new key + migrateUsed for token signing, not encryption
AWS Managed Keys✅ AutomaticN/ANo user control over schedule

For asymmetric keys requiring rotation, plan a migration strategy well in advance. This involves creating a new key, updating application configuration, re-encrypting existing data (or accepting dual-key periods), and eventually scheduling deletion of the old key. On legal-tech platforms handling signed documents, I've found that maintaining a key registry table mapping document IDs to their signing key version simplifies this significantly.

Enabling Rotation Safely

# Enable automatic rotation
aws kms enable-key-rotation --key-id mrk-abc123def456

# Verify status
aws kms get-key-rotation-status --key-id mrk-abc123def456

# Check next rotation date
aws kms describe-key --key-id mrk-abc123def456 \
  --query 'KeyMetadata.NextRotationDate'

Enable rotation immediately after key creation. There is no operational downside — old backing keys remain available indefinitely for decrypting historical data. Disabling rotation later does not delete previous versions; it simply stops generating new ones.

How Do You Integrate AWS KMS Encryption Into Laravel Applications Securely?

Integration extends beyond code. Infrastructure configuration determines whether your encryption actually protects data or just adds complexity. For teams evaluating cloud hosting versus traditional options, KMS availability often tips the scale toward AWS for regulated workloads.

IAM Role Configuration Over Static Credentials

Never store AWS access keys in .env files. EC2 instances and Lambda functions should assume IAM roles with minimal KMS permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:GenerateDataKey"
            ],
            "Resource": "arn:aws:kms:ap-south-1:123456789012:key/mrk-abc123def456"
        }
    ]
}

This role grants only decryption capabilities — sufficient for reading encrypted records but preventing accidental or malicious encryption of new data with the wrong key. Separate roles for write-heavy services enforce separation of concerns.

Handling Decryption Failures Gracefully

KMS calls fail for legitimate reasons: throttling, network issues, disabled keys, or deleted keys. Your application must handle these explicitly:

  • Throttling: Implement exponential backoff with jitter; KMS defaults to 12,000 requests/second per account but shared tenancy can cause bursts
  • Disabled keys: Log the key ID and alert operations; this indicates intentional suspension requiring investigation
  • Deleted keys: Data is unrecoverable after the waiting period expires; ensure monitoring catches scheduled deletions before completion
  • Access denied: Verify IAM role assumptions and key policy conditions; test with aws sts get-caller-identity to confirm assumed role

For high-throughput applications, consider caching decrypted data keys in Redis with short TTLs (minutes, not hours). This reduces KMS dependency during traffic spikes while maintaining reasonable security bounds. Always encrypt cached keys with a separate local master key stored in Secrets Manager.

Testing Encryption Without Production Risk

Use KMS key policies to create test-specific keys with relaxed conditions. Never test against production CMKs. AWS also provides local testing tools like aws-encryption-cli for offline validation of envelope encryption logic before deployment.

Secure Implementation Checklist for Encrypt Data with AWS KMS: Keys, Policies, Rotation

Successfully implementing encrypt data with AWS KMS: Keys, Policies, Rotation requires attention to detail across configuration, code, and operations. Start with symmetric customer-managed keys for application data unless you have documented requirements for asymmetric cryptography. Implement envelope encryption to avoid rate limits and excessive costs. Write key policies with explicit principals and restrictive conditions rather than permissive wildcards. Enable automatic rotation on day one for all eligible keys. Configure IAM roles instead of static credentials, and build robust error handling for KMS API failures.

These practices form the foundation of production-grade encryption that satisfies auditors while remaining maintainable by development teams. If you're building compliance-sensitive applications and need guidance on secure architecture, reach out to discuss your encryption requirements.

Frequently Asked Questions

Symmetric keys use a single secret for both encryption and decryption, ideal for encrypting data at rest or envelope encryption. Asymmetric keys use a public/private pair, suited for digital signatures or encrypting small payloads outside AWS where the private key must never leave KMS.

Each customer-managed key costs USD 1.00 (approx NPR 135) monthly plus USD 0.03 per 10,000 API requests. AWS-managed keys are free but offer no custom policies or rotation control. Budget roughly NPR 2,000–3,000 monthly for moderate production usage including API calls.

Use AWS-managed keys only for default service integration with zero administrative overhead. Choose customer-managed keys when you need custom key policies, automatic annual rotation, audit trails via CloudTrail, cross-account access, or compliance requirements demanding explicit key ownership and lifecycle control.

Attach a resource-based policy directly to the CMK allowing kms:Encrypt and kms:Decrypt actions for specific IAM role ARNs. Unlike IAM identity policies, key policies are authoritative; even administrators cannot use a key unless explicitly permitted in its resource policy. Always scope principals to exact ARNs, not wildcards.

Yes, enable automatic annual rotation on symmetric CMKs. AWS retains previous key versions indefinitely to decrypt existing ciphertext transparently. Applications require no code changes since the key ID remains constant. Manual rotation requires re-encrypting all data with a new key ID, causing operational overhead and potential downtime during migration.

Data becomes permanently unrecoverable after the mandatory waiting period expires, typically 7 to 30 days. AWS cannot restore deleted keys or decrypt affected ciphertext. Always disable keys first and monitor CloudTrail logs for unexpected decryption failures before scheduling deletion. Treat key deletion as irreversible destruction of all associated encrypted data.

Generate a unique data key via GenerateDataKey, use the plaintext copy to encrypt your payload locally, then store only the encrypted data key alongside the ciphertext. Discard the plaintext immediately. This avoids sending large payloads to KMS, reduces API costs, and limits exposure of master keys while maintaining centralized key management.

The Lambda execution role lacks kms:Decrypt permission in either the IAM policy or the KMS key policy. Both must grant access; one alone is insufficient. Verify the key policy includes the Lambda function ARN or role ARN explicitly. Check CloudTrail for denied requests showing the exact missing action and principal.

Add external account IDs as principals in the KMS key policy with specific allowed actions. The external account must also attach an IAM policy granting its users permission to use that key. This two-way trust prevents unauthorized cross-account access while enabling secure multi-account encryption workflows without copying keys.

KMS provides FIPS 140-2 validated HSM-backed key storage suitable for handling sensitive legal documents and client data. Key policies and CloudTrail logging satisfy audit requirements for access control and non-repudiation. For Nepal Divorce Services and similar portals, this meets reasonable security expectations without managing physical HSM infrastructure or complex on-premise key ceremonies.

Replace plaintext credentials in .env with SSM Parameter Store SecureString parameters backed by KMS. Update config files to fetch decrypted values at runtime using aws/aws-sdk-php-laravel. Remove all committed secrets from version control immediately. Test thoroughly in staging first, as misconfigured key policies cause silent failures during cache warmup or queue worker startup.

Yes, import key material into KMS using ImportKeyMaterial for compliance requiring external key generation. Imported keys cannot be rotated automatically and expire based on your provided expiration timestamp. You must manage the original key material externally for re-import. This suits jurisdictions mandating sovereign key generation while retaining AWS operational integration.

Enable CloudTrail logging for all KMS API calls across regions. Create CloudWatch alarms for Decrypt and GenerateDataKey failures exceeding thresholds. Set up SNS notifications for administrative actions like DisableKey or ScheduleKeyDeletion. Regular audit logs reveal usage patterns, identify compromised credentials attempting decryption, and provide forensic evidence for security incident response.

Excessive GenerateDataKey calls create latency and cost spikes. Implement local caching of encrypted data keys with TTLs under five minutes. Batch encryption operations where possible. Use regional endpoints to avoid cross-region latency. Monitor throttling via CloudMetrics; request service quota increases proactively before peak traffic events like Dashain sales periods.

Use LocalStack or moto libraries to mock KMS APIs during development and CI pipelines. These simulate key creation, encryption, and policy evaluation without AWS charges. Reserve real KMS testing for staging environments with dedicated test keys. Never use production keys in automated tests; accidental deletions or excessive API calls risk data loss and billing surprises.

Share this article

Quick Contact Options
Choose how you want to connect me: