Create AWS Certificate Manager Private Certificate Authorities

The aws:acmpca/certificateAuthority:CertificateAuthority resource, part of the Pulumi AWS provider, defines a private certificate authority within AWS Certificate Manager Private CA: its cryptographic configuration, usage mode, and revocation settings. This guide focuses on three capabilities: basic CA configuration with key algorithms and subject identity, short-lived certificate mode for reduced revocation overhead, and CRL publishing to S3 for certificate revocation.

Creating a CA leaves it in PENDING_CERTIFICATE status; you must sign the CSR using the CertificateAuthorityCertificate resource to activate it. CRL configurations require S3 buckets with ACM PCA service permissions. The examples are intentionally small. Combine them with your own signing workflows and storage infrastructure.

Create a private CA with standard configuration

Most private CA deployments start with a basic authority that defines the key algorithm, signing algorithm, and subject identity.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.acmpca.CertificateAuthority("example", {
    certificateAuthorityConfiguration: {
        keyAlgorithm: "RSA_4096",
        signingAlgorithm: "SHA512WITHRSA",
        subject: {
            commonName: "example.com",
        },
    },
    permanentDeletionTimeInDays: 7,
});
import pulumi
import pulumi_aws as aws

example = aws.acmpca.CertificateAuthority("example",
    certificate_authority_configuration={
        "key_algorithm": "RSA_4096",
        "signing_algorithm": "SHA512WITHRSA",
        "subject": {
            "common_name": "example.com",
        },
    },
    permanent_deletion_time_in_days=7)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/acmpca"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := acmpca.NewCertificateAuthority(ctx, "example", &acmpca.CertificateAuthorityArgs{
			CertificateAuthorityConfiguration: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationArgs{
				KeyAlgorithm:     pulumi.String("RSA_4096"),
				SigningAlgorithm: pulumi.String("SHA512WITHRSA"),
				Subject: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs{
					CommonName: pulumi.String("example.com"),
				},
			},
			PermanentDeletionTimeInDays: pulumi.Int(7),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Acmpca.CertificateAuthority("example", new()
    {
        CertificateAuthorityConfiguration = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs
        {
            KeyAlgorithm = "RSA_4096",
            SigningAlgorithm = "SHA512WITHRSA",
            Subject = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs
            {
                CommonName = "example.com",
            },
        },
        PermanentDeletionTimeInDays = 7,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.acmpca.CertificateAuthority;
import com.pulumi.aws.acmpca.CertificateAuthorityArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new CertificateAuthority("example", CertificateAuthorityArgs.builder()
            .certificateAuthorityConfiguration(CertificateAuthorityCertificateAuthorityConfigurationArgs.builder()
                .keyAlgorithm("RSA_4096")
                .signingAlgorithm("SHA512WITHRSA")
                .subject(CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs.builder()
                    .commonName("example.com")
                    .build())
                .build())
            .permanentDeletionTimeInDays(7)
            .build());

    }
}
resources:
  example:
    type: aws:acmpca:CertificateAuthority
    properties:
      certificateAuthorityConfiguration:
        keyAlgorithm: RSA_4096
        signingAlgorithm: SHA512WITHRSA
        subject:
          commonName: example.com
      permanentDeletionTimeInDays: 7

The certificateAuthorityConfiguration block specifies RSA_4096 for the key algorithm and SHA512WITHRSA for signing. The subject defines the CA’s identity (here, example.com). The permanentDeletionTimeInDays property sets a 7-day recovery window after deletion. This creates a SUBORDINATE CA by default; the CA remains in PENDING_CERTIFICATE status until you sign its CSR using the CertificateAuthorityCertificate resource.

Configure a CA for short-lived certificates

Applications that rotate credentials frequently can use short-lived certificates (valid up to 7 days) to reduce revocation overhead.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.acmpca.CertificateAuthority("example", {
    usageMode: "SHORT_LIVED_CERTIFICATE",
    certificateAuthorityConfiguration: {
        keyAlgorithm: "RSA_4096",
        signingAlgorithm: "SHA512WITHRSA",
        subject: {
            commonName: "example.com",
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.acmpca.CertificateAuthority("example",
    usage_mode="SHORT_LIVED_CERTIFICATE",
    certificate_authority_configuration={
        "key_algorithm": "RSA_4096",
        "signing_algorithm": "SHA512WITHRSA",
        "subject": {
            "common_name": "example.com",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/acmpca"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := acmpca.NewCertificateAuthority(ctx, "example", &acmpca.CertificateAuthorityArgs{
			UsageMode: pulumi.String("SHORT_LIVED_CERTIFICATE"),
			CertificateAuthorityConfiguration: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationArgs{
				KeyAlgorithm:     pulumi.String("RSA_4096"),
				SigningAlgorithm: pulumi.String("SHA512WITHRSA"),
				Subject: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs{
					CommonName: pulumi.String("example.com"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Acmpca.CertificateAuthority("example", new()
    {
        UsageMode = "SHORT_LIVED_CERTIFICATE",
        CertificateAuthorityConfiguration = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs
        {
            KeyAlgorithm = "RSA_4096",
            SigningAlgorithm = "SHA512WITHRSA",
            Subject = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs
            {
                CommonName = "example.com",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.acmpca.CertificateAuthority;
import com.pulumi.aws.acmpca.CertificateAuthorityArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new CertificateAuthority("example", CertificateAuthorityArgs.builder()
            .usageMode("SHORT_LIVED_CERTIFICATE")
            .certificateAuthorityConfiguration(CertificateAuthorityCertificateAuthorityConfigurationArgs.builder()
                .keyAlgorithm("RSA_4096")
                .signingAlgorithm("SHA512WITHRSA")
                .subject(CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs.builder()
                    .commonName("example.com")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:acmpca:CertificateAuthority
    properties:
      usageMode: SHORT_LIVED_CERTIFICATE
      certificateAuthorityConfiguration:
        keyAlgorithm: RSA_4096
        signingAlgorithm: SHA512WITHRSA
        subject:
          commonName: example.com

Setting usageMode to SHORT_LIVED_CERTIFICATE optimizes the CA for certificates that expire quickly. This mode allows you to omit revocation configuration since certificates expire before revocation becomes necessary. The certificateAuthorityConfiguration remains the same as the basic example.

Enable certificate revocation with S3 storage

General-purpose CAs need revocation mechanisms to invalidate compromised certificates before they expire. ACM PCA publishes Certificate Revocation Lists (CRLs) to S3.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.s3.Bucket("example", {
    bucket: "example",
    forceDestroy: true,
});
const acmpcaBucketAccess = aws.iam.getPolicyDocumentOutput({
    statements: [{
        actions: [
            "s3:GetBucketAcl",
            "s3:GetBucketLocation",
            "s3:PutObject",
            "s3:PutObjectAcl",
        ],
        resources: [
            example.arn,
            pulumi.interpolate`${example.arn}/*`,
        ],
        principals: [{
            identifiers: ["acm-pca.amazonaws.com"],
            type: "Service",
        }],
    }],
});
const exampleBucketPolicy = new aws.s3.BucketPolicy("example", {
    bucket: example.id,
    policy: acmpcaBucketAccess.apply(acmpcaBucketAccess => acmpcaBucketAccess.json),
});
const exampleCertificateAuthority = new aws.acmpca.CertificateAuthority("example", {
    certificateAuthorityConfiguration: {
        keyAlgorithm: "RSA_4096",
        signingAlgorithm: "SHA512WITHRSA",
        subject: {
            commonName: "example.com",
        },
    },
    revocationConfiguration: {
        crlConfiguration: {
            customCname: "crl.example.com",
            enabled: true,
            expirationInDays: 7,
            s3BucketName: example.id,
            s3ObjectAcl: "BUCKET_OWNER_FULL_CONTROL",
        },
    },
}, {
    dependsOn: [exampleBucketPolicy],
});
import pulumi
import pulumi_aws as aws

example = aws.s3.Bucket("example",
    bucket="example",
    force_destroy=True)
acmpca_bucket_access = aws.iam.get_policy_document_output(statements=[{
    "actions": [
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:PutObject",
        "s3:PutObjectAcl",
    ],
    "resources": [
        example.arn,
        example.arn.apply(lambda arn: f"{arn}/*"),
    ],
    "principals": [{
        "identifiers": ["acm-pca.amazonaws.com"],
        "type": "Service",
    }],
}])
example_bucket_policy = aws.s3.BucketPolicy("example",
    bucket=example.id,
    policy=acmpca_bucket_access.json)
example_certificate_authority = aws.acmpca.CertificateAuthority("example",
    certificate_authority_configuration={
        "key_algorithm": "RSA_4096",
        "signing_algorithm": "SHA512WITHRSA",
        "subject": {
            "common_name": "example.com",
        },
    },
    revocation_configuration={
        "crl_configuration": {
            "custom_cname": "crl.example.com",
            "enabled": True,
            "expiration_in_days": 7,
            "s3_bucket_name": example.id,
            "s3_object_acl": "BUCKET_OWNER_FULL_CONTROL",
        },
    },
    opts = pulumi.ResourceOptions(depends_on=[example_bucket_policy]))
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/acmpca"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
			Bucket:       pulumi.String("example"),
			ForceDestroy: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		acmpcaBucketAccess := iam.GetPolicyDocumentOutput(ctx, iam.GetPolicyDocumentOutputArgs{
			Statements: iam.GetPolicyDocumentStatementArray{
				&iam.GetPolicyDocumentStatementArgs{
					Actions: pulumi.StringArray{
						pulumi.String("s3:GetBucketAcl"),
						pulumi.String("s3:GetBucketLocation"),
						pulumi.String("s3:PutObject"),
						pulumi.String("s3:PutObjectAcl"),
					},
					Resources: pulumi.StringArray{
						example.Arn,
						example.Arn.ApplyT(func(arn string) (string, error) {
							return fmt.Sprintf("%v/*", arn), nil
						}).(pulumi.StringOutput),
					},
					Principals: iam.GetPolicyDocumentStatementPrincipalArray{
						&iam.GetPolicyDocumentStatementPrincipalArgs{
							Identifiers: pulumi.StringArray{
								pulumi.String("acm-pca.amazonaws.com"),
							},
							Type: pulumi.String("Service"),
						},
					},
				},
			},
		}, nil)
		exampleBucketPolicy, err := s3.NewBucketPolicy(ctx, "example", &s3.BucketPolicyArgs{
			Bucket: example.ID(),
			Policy: pulumi.String(acmpcaBucketAccess.ApplyT(func(acmpcaBucketAccess iam.GetPolicyDocumentResult) (*string, error) {
				return &acmpcaBucketAccess.Json, nil
			}).(pulumi.StringPtrOutput)),
		})
		if err != nil {
			return err
		}
		_, err = acmpca.NewCertificateAuthority(ctx, "example", &acmpca.CertificateAuthorityArgs{
			CertificateAuthorityConfiguration: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationArgs{
				KeyAlgorithm:     pulumi.String("RSA_4096"),
				SigningAlgorithm: pulumi.String("SHA512WITHRSA"),
				Subject: &acmpca.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs{
					CommonName: pulumi.String("example.com"),
				},
			},
			RevocationConfiguration: &acmpca.CertificateAuthorityRevocationConfigurationArgs{
				CrlConfiguration: &acmpca.CertificateAuthorityRevocationConfigurationCrlConfigurationArgs{
					CustomCname:      pulumi.String("crl.example.com"),
					Enabled:          pulumi.Bool(true),
					ExpirationInDays: pulumi.Int(7),
					S3BucketName:     example.ID(),
					S3ObjectAcl:      pulumi.String("BUCKET_OWNER_FULL_CONTROL"),
				},
			},
		}, pulumi.DependsOn([]pulumi.Resource{
			exampleBucketPolicy,
		}))
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.S3.Bucket("example", new()
    {
        BucketName = "example",
        ForceDestroy = true,
    });

    var acmpcaBucketAccess = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Actions = new[]
                {
                    "s3:GetBucketAcl",
                    "s3:GetBucketLocation",
                    "s3:PutObject",
                    "s3:PutObjectAcl",
                },
                Resources = new[]
                {
                    example.Arn,
                    $"{example.Arn}/*",
                },
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Identifiers = new[]
                        {
                            "acm-pca.amazonaws.com",
                        },
                        Type = "Service",
                    },
                },
            },
        },
    });

    var exampleBucketPolicy = new Aws.S3.BucketPolicy("example", new()
    {
        Bucket = example.Id,
        Policy = acmpcaBucketAccess.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var exampleCertificateAuthority = new Aws.Acmpca.CertificateAuthority("example", new()
    {
        CertificateAuthorityConfiguration = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs
        {
            KeyAlgorithm = "RSA_4096",
            SigningAlgorithm = "SHA512WITHRSA",
            Subject = new Aws.Acmpca.Inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs
            {
                CommonName = "example.com",
            },
        },
        RevocationConfiguration = new Aws.Acmpca.Inputs.CertificateAuthorityRevocationConfigurationArgs
        {
            CrlConfiguration = new Aws.Acmpca.Inputs.CertificateAuthorityRevocationConfigurationCrlConfigurationArgs
            {
                CustomCname = "crl.example.com",
                Enabled = true,
                ExpirationInDays = 7,
                S3BucketName = example.Id,
                S3ObjectAcl = "BUCKET_OWNER_FULL_CONTROL",
            },
        },
    }, new CustomResourceOptions
    {
        DependsOn =
        {
            exampleBucketPolicy,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.s3.BucketPolicy;
import com.pulumi.aws.s3.BucketPolicyArgs;
import com.pulumi.aws.acmpca.CertificateAuthority;
import com.pulumi.aws.acmpca.CertificateAuthorityArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityRevocationConfigurationArgs;
import com.pulumi.aws.acmpca.inputs.CertificateAuthorityRevocationConfigurationCrlConfigurationArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Bucket("example", BucketArgs.builder()
            .bucket("example")
            .forceDestroy(true)
            .build());

        final var acmpcaBucketAccess = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .actions(                
                    "s3:GetBucketAcl",
                    "s3:GetBucketLocation",
                    "s3:PutObject",
                    "s3:PutObjectAcl")
                .resources(                
                    example.arn(),
                    example.arn().applyValue(_arn -> String.format("%s/*", _arn)))
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .identifiers("acm-pca.amazonaws.com")
                    .type("Service")
                    .build())
                .build())
            .build());

        var exampleBucketPolicy = new BucketPolicy("exampleBucketPolicy", BucketPolicyArgs.builder()
            .bucket(example.id())
            .policy(acmpcaBucketAccess.applyValue(_acmpcaBucketAccess -> _acmpcaBucketAccess.json()))
            .build());

        var exampleCertificateAuthority = new CertificateAuthority("exampleCertificateAuthority", CertificateAuthorityArgs.builder()
            .certificateAuthorityConfiguration(CertificateAuthorityCertificateAuthorityConfigurationArgs.builder()
                .keyAlgorithm("RSA_4096")
                .signingAlgorithm("SHA512WITHRSA")
                .subject(CertificateAuthorityCertificateAuthorityConfigurationSubjectArgs.builder()
                    .commonName("example.com")
                    .build())
                .build())
            .revocationConfiguration(CertificateAuthorityRevocationConfigurationArgs.builder()
                .crlConfiguration(CertificateAuthorityRevocationConfigurationCrlConfigurationArgs.builder()
                    .customCname("crl.example.com")
                    .enabled(true)
                    .expirationInDays(7)
                    .s3BucketName(example.id())
                    .s3ObjectAcl("BUCKET_OWNER_FULL_CONTROL")
                    .build())
                .build())
            .build(), CustomResourceOptions.builder()
                .dependsOn(exampleBucketPolicy)
                .build());

    }
}
resources:
  example:
    type: aws:s3:Bucket
    properties:
      bucket: example
      forceDestroy: true
  exampleBucketPolicy:
    type: aws:s3:BucketPolicy
    name: example
    properties:
      bucket: ${example.id}
      policy: ${acmpcaBucketAccess.json}
  exampleCertificateAuthority:
    type: aws:acmpca:CertificateAuthority
    name: example
    properties:
      certificateAuthorityConfiguration:
        keyAlgorithm: RSA_4096
        signingAlgorithm: SHA512WITHRSA
        subject:
          commonName: example.com
      revocationConfiguration:
        crlConfiguration:
          customCname: crl.example.com
          enabled: true
          expirationInDays: 7
          s3BucketName: ${example.id}
          s3ObjectAcl: BUCKET_OWNER_FULL_CONTROL
    options:
      dependsOn:
        - ${exampleBucketPolicy}
variables:
  acmpcaBucketAccess:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - actions:
              - s3:GetBucketAcl
              - s3:GetBucketLocation
              - s3:PutObject
              - s3:PutObjectAcl
            resources:
              - ${example.arn}
              - ${example.arn}/*
            principals:
              - identifiers:
                  - acm-pca.amazonaws.com
                type: Service

The revocationConfiguration block enables CRL publishing. The crlConfiguration specifies the S3 bucket name, expiration period (7 days), and optional custom CNAME for CRL distribution. The bucket policy grants the acm-pca.amazonaws.com service permissions to write CRLs. The dependsOn ensures the bucket policy exists before creating the CA, preventing permission errors during CRL publishing.

Beyond these examples

These snippets focus on specific certificate authority features: CA configuration, usage modes for certificate lifecycle, and CRL publishing to S3. They’re intentionally minimal rather than full PKI deployments.

The examples may reference pre-existing infrastructure such as S3 buckets with ACM PCA service permissions (for CRL example). They focus on configuring the CA rather than provisioning the complete certificate lifecycle.

To keep things focused, common CA patterns are omitted, including:

  • CA activation via CertificateAuthorityCertificate resource
  • ROOT vs SUBORDINATE CA types (type property)
  • OCSP responder configuration (ocspConfiguration)
  • Key storage security standards (keyStorageSecurityStandard)

These omissions are intentional: the goal is to illustrate how each CA feature is wired, not provide drop-in PKI modules. See the ACM PCA CertificateAuthority resource reference for all available configuration options.

Let's create AWS Certificate Manager Private Certificate Authorities

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Setup & Activation
Why can't my certificate authority issue certificates after creation?
Newly created CAs start in PENDING_CERTIFICATE status and cannot issue certificates until you sign the certificate signing request (CSR).
How do I activate my certificate authority?
Sign the CSR available in the certificateSigningRequest attribute. Use the aws.acmpca.CertificateAuthorityCertificate resource to complete this setup.
Why can't I disable my certificate authority?
You can only set enabled to false when the CA is in an ACTIVE state. Ensure the CA is fully activated before attempting to disable it.
CA Types & Usage Modes
What's the difference between ROOT and SUBORDINATE certificate authorities?
ROOT CAs are self-signed and sit at the top of the trust hierarchy, while SUBORDINATE CAs (the default) are signed by a parent CA. The type property is immutable after creation.
When should I use SHORT_LIVED_CERTIFICATE mode?
Use SHORT_LIVED_CERTIFICATE for certificates with 7-day maximum validity that expire quickly and may optionally omit revocation. Use GENERAL_PURPOSE (default) for standard certificates requiring revocation mechanisms.
What properties can't be changed after creation?
Both type (ROOT vs SUBORDINATE) and keyStorageSecurityStandard (FIPS compliance level) are immutable. Choose these values carefully during initial creation.
Certificate Revocation
What S3 permissions are required for certificate revocation lists?
Grant the acm-pca.amazonaws.com service principal these permissions: s3:GetBucketAcl, s3:GetBucketLocation, s3:PutObject, and s3:PutObjectAcl on both the bucket and its objects.
How do I enable certificate revocation?
Configure revocationConfiguration with crlConfiguration settings including an S3 bucket name, expiration days, and optional custom CNAME. Ensure the S3 bucket policy is in place before creating the CA (use dependsOn).
Lifecycle & Deletion
How long can I restore a deleted certificate authority?
Deleted CAs are restorable for 7 to 30 days (default 30). Configure this with permanentDeletionTimeInDays.
What FIPS compliance levels are available for CA keys?
Choose FIPS_140_2_LEVEL_3_OR_HIGHER (default) or FIPS_140_2_LEVEL_2_OR_HIGHER. This setting is immutable and region-specific support varies.

Using a different cloud?

Explore security guides for other cloud providers: