Prerequisites
AWS Account Requirements
- ✓ AWS account with at least one Private CA in ACM PCA
- ✓ IAM identity with
acm-pca:ListCertificateAuthoritiesandacm-pca:GetCertificateAuthorityCertificate - → For GovCloud (Federal/DoD): access to
us-gov-west-1orus-gov-east-1
Scanner Requirements
- ✓ Outbound HTTPS (443) to
acm-pca.{region}.amazonaws.com - ✓ No AWS SDK installed — all API calls use stdlib SigV4 signing
- ✓ Runs on Windows, Linux, macOS — cross-platform with
CGO_ENABLED=0
How It Works
Architecture
-scan-pki
SigV4-signed HTTPS
paginated, all statuses
⚠ Requirement review: EXPIRED CA status currently maps to
valid in certificate.pki_revocation_status. Semantically questionable — EXPIRED should map to a distinct value (e.g. expired). Tracked for correction; test against current behavior but treat as a known defect.
PEM cert per CA
What Gets Discovered
- • All CAs in each configured region (ROOT, SUBORDINATE)
- • CA certificate PEM → full x509 parse → PQC assessment
- •
SourceFilePathset toawspca://region/arn - • SHA-256 deduplication prevents duplicates across regions
What Is NOT Collected
- • Private keys (never accessible via PCA API)
- • Issued leaf certificate content (only the CA cert itself)
- • CRL or OCSP responder payloads
No AWS SDK Dependency
The connector signs all requests using a native SigV4 implementation (stdlib crypto/hmac + crypto/sha256). This eliminates the github.com/aws/aws-sdk-go-v2 dependency and all of its transitive dependencies, keeping the binary small and supply-chain risk minimal.
Four-Tier Credential Chain
The scanner tries credentials in this order and uses the first one that resolves. Credentials are never accepted on the command line — they must be stored in config.enc, environment variables, the AWS credentials file, or an EC2 instance role.
config.enc (encrypted storage)
Set via -config -config-awspca-key <AKID> -config-awspca-secret <secret>. Stored AES-256-GCM encrypted on disk. Recommended for managed/unattended deployments.
Environment variables
AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY. Optionally AWS_SESSION_TOKEN for STS temporary credentials. Used in CI/CD pipelines and container environments.
~/.aws/credentials file
INI format. Profile selected by AWS_PROFILE env var (defaults to default). Fields: aws_access_key_id, aws_secret_access_key, aws_session_token.
IMDSv2 (EC2 instance role)
Uses the EC2 Instance Metadata Service v2 (PUT-then-GET token flow). IMDSv1 is intentionally not used. When running in EC2 with an attached IAM role, no credential configuration is required.
Federal Government / DoD Configuration
GovCloud, FIPS, C2S, and SC2S are all supported
The scanner supports all AWS environments used in Federal and DoD deployments. Select the appropriate configuration for your environment below.
GovCloud — Standard endpoint
AWS GovCloud uses standard region names with US Government access controls. No special endpoint configuration is needed unless FIPS mode is required.
# Store GovCloud region (us-gov-west-1 or us-gov-east-1)
certscanner -config -config-awspca-region us-gov-west-1 -config-awspca-key AKID -config-awspca-secret SECRET
# Run scan
certscanner -scan-pki
GovCloud + FIPS — Force FIPS endpoint
Required when the environment policy mandates FIPS 140-2 validated TLS. Forces use of acm-pca-fips.{region}.amazonaws.com.
# Enable FIPS endpoint
certscanner -config \
-config-awspca-region us-gov-west-1 \
-config-awspca-key AKID \
-config-awspca-secret SECRET \
-config-awspca-fips
C2S / SC2S — Custom endpoint override
Intelligence Community (C2S) and Secret (SC2S) environments use non-public endpoints. Specify the full endpoint URL. This overrides region-based endpoint construction entirely.
# C2S example (endpoint URL provided by your Cloud Service Provider)
certscanner -config \
-config-awspca-region us-iso-east-1 \
-config-awspca-key AKID \
-config-awspca-secret SECRET \
-config-awspca-endpoint https://acm-pca.us-iso-east-1.c2s.ic.gov
# SC2S example
certscanner -config \
-config-awspca-region us-isob-east-1 \
-config-awspca-key AKID \
-config-awspca-secret SECRET \
-config-awspca-endpoint https://acm-pca.us-isob-east-1.sc2s.sgov.gov
Multi-Region (JRSS / Multi-Cloud Agency)
A comma-separated list of regions will be scanned sequentially. Each region resolves credentials and endpoints independently.
certscanner -config \
-config-awspca-region "us-gov-west-1,us-gov-east-1" \
-config-awspca-key AKID \
-config-awspca-secret SECRET
Configuration Reference
Stored Flags (written to config.enc)
| Flag | Description | Example |
|---|---|---|
| -config-awspca-region | AWS region(s) — comma-separated for multi-region | us-east-1,us-gov-west-1 |
| -config-awspca-key | AWS access key ID. Falls back to env vars / credentials file / IMDSv2 if empty. | AKIAIOSFODNN7EXAMPLE |
| -config-awspca-secret | AWS secret access key. Encrypted in config.enc. | (redacted) |
| -config-awspca-endpoint | Custom endpoint URL for FIPS, C2S, or SC2S. Overrides all auto-built endpoints. | https://acm-pca-fips.us-gov-west-1.amazonaws.com |
| -config-awspca-fips | Force FIPS endpoint for all configured regions (boolean flag) | (no value needed) |
Runtime Override Flags (one-scan, not stored)
| Flag | Description |
|---|---|
| -awspca-endpoint | Override the AWS PCA endpoint for this scan only. Useful for local testing with a mock server. Not written to config.enc. |
| -insecure | Skip TLS certificate verification. Not recommended. Use only for troubleshooting with self-signed endpoints. |
Quick Start
Step 1 — Store credentials
# Store region and credentials in config.enc
certscanner -config \
-config-awspca-region us-east-1 \
-config-awspca-key AKIAIOSFODNN7EXAMPLE \
-config-awspca-secret wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Step 2 — Run the PKI scan
certscanner -scan-pki -outputformat flatndjson -output pki-report.ndjson
Configure your license using TYCHON_LICENSE_KEY or a license file before scanning. See License Configuration.
Expected output:
Scanning AWS Private CA for CA certificates...
[pki] awspca: using credentials from config.enc for region us-east-1
[pki] awspca: found 3 certificate authorities in region us-east-1
[pki] awspca: fetching certificate for arn:aws:acm-pca:us-east-1:...
[pki] awspca: discovered 3 unique CA certificate(s) across 1 region(s)
AWS PCA scan complete: 3 CA certificate(s) discovered.
Using EC2 instance role (no credentials needed)
# Only region is required — credentials come from the EC2 instance role via IMDSv2
certscanner -config -config-awspca-region us-east-1
# Run scan — credentials auto-resolved via IMDSv2
certscanner -scan-pki
Using environment variables (CI/CD pipelines)
# Set region in config.enc (or pass via -config-awspca-region)
certscanner -config -config-awspca-region us-east-1
# At scan time, export env vars — these take priority over ~/.aws/credentials
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_SESSION_TOKEN=FwoGZXIvYXdz... # STS temporary credential
certscanner -scan-pki
Minimum IAM Policy
The scanner makes exactly two AWS PCA API calls. Attach this policy to the IAM user, role, or instance profile — nothing beyond these two read actions is required.
API Actions Granted (Read-Only)
- acm-pca:ListCertificateAuthorities
- acm-pca:GetCertificateAuthorityCertificate
Actions Never Granted
- acm-pca:IssueCertificate
- acm-pca:RevokeCertificate
- acm-pca:DeleteCertificateAuthority
- acm-pca:UpdateCertificateAuthority
- acm-pca:CreateCertificateAuthority
- acm-pca:ImportCertificateAuthorityCertificate
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TychonPCAScanReadOnly",
"Effect": "Allow",
"Action": [
"acm-pca:ListCertificateAuthorities",
"acm-pca:GetCertificateAuthorityCertificate"
],
"Resource": "*"
}
]
}
Scope down Resource when possible. In high-security environments, replace * with the ARNs of specific CAs: arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/*
Create a Dedicated IAM User (AWS CLI)
Use a dedicated IAM user rather than a root account or an existing identity with broader permissions. Store the resulting access key in config.enc — never on the command line.
# Create the user
aws iam create-user --user-name tychon-pki-scanner
# Attach the inline policy
aws iam put-user-policy \
--user-name tychon-pki-scanner \
--policy-name TychonPCAScanReadOnly \
--policy-document '{
"Version":"2012-10-17",
"Statement":[{
"Sid":"TychonPCAScanReadOnly",
"Effect":"Allow",
"Action":["acm-pca:ListCertificateAuthorities","acm-pca:GetCertificateAuthorityCertificate"],
"Resource":"*"
}]
}'
# Generate access keys — store output in config.enc
aws iam create-access-key --user-name tychon-pki-scanner
On EC2, prefer an instance IAM role over a long-lived access key. The connector resolves instance-role credentials through IMDSv2. It does not fetch credentials from the ECS task-role endpoint. On ECS or Lambda, ensure credentials are available through a supported source, such as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN for temporary credentials. If you use a long-lived access key, set a strict key rotation policy in IAM.
Output Fields
Each CA certificate discovered generates a pki_ca_discovered event with event.dataset: pki_certificate. All cryptographic fields follow the standard ECS namespace (x509.*, certificate.*). PKI platform metadata lives in tychon.pki.*.
| Field | Example Value | Notes |
|---|---|---|
| event.action | pki_ca_discovered | Fixed value for all AWS PCA CA certificates |
| event.dataset | pki_certificate | Routes to tychon-pqc-certificates Elasticsearch index |
| certificate.source_file_path | awspca://us-east-1/arn:aws:acm-pca:... | Queryable as source_file_path:awspca://* in Kibana |
| tychon.pki.platform.type | aws_pca | Platform identifier — consistent across Kibana / Splunk |
| tychon.pki.platform.host | acm-pca.us-east-1.amazonaws.com | Derived from the configured region (or custom endpoint) |
| tychon.pki.platform.source_proto | https | Always HTTPS (SigV4-signed REST) |
| tychon.pki.ca.name | arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/… | Full ARN of the CA |
| x509.not_before | 2024-01-15T00:00:00Z | Certificate valid-from (RFC 3339) |
| x509.not_after | 2034-01-15T00:00:00Z | Certificate expiration (RFC 3339) |
| certificate.not_before | 2024-01-15T00:00:00Z | Alias of x509.not_before |
| certificate.not_after | 2034-01-15T00:00:00Z | Alias of x509.not_after |
| certificate.pqc_vulnerable | true | True when key algorithm is RSA/ECDSA (quantum-vulnerable) |
| certificate.sha256_fingerprint | 3b4c…e1f2 | Dedup key — same cert produces same event.id regardless of which scanner found it |
Troubleshooting
HTTP 403 InvalidSignatureException
Cause: The SigV4 signature was rejected. Most commonly caused by a clock skew >5 minutes or incorrect secret key.
Fix: Ensure system time is synchronized (NTP). Re-store credentials: certscanner -config -config-awspca-key <AKID> -config-awspca-secret <correct-secret>
HTTP 403 AccessDeniedException
Cause: The IAM identity lacks the required permissions.
Fix: Attach the minimum IAM policy to the user or role. In GovCloud, ensure the policy is created in the GovCloud partition.
HTTP 400 ResourceNotFoundException
Cause: The CA was deleted or does not exist in the specified region. Can also occur when the endpoint resolves to the wrong region.
Fix: Verify the region in config.enc: certscanner -config -config-awspca-region us-east-1
No credentials found
Cause: All four credential tiers exhausted — no keys in config.enc, no env vars, no credentials file, and not running on EC2 with an IAM role.
Fix: Store credentials: certscanner -config -config-awspca-key <AKID> -config-awspca-secret <secret>, or export AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY.
IMDSv2 token request failed (not on EC2?)
Cause: The scanner is not running on EC2, or the IMDSv2 endpoint (169.254.169.254) is not reachable (e.g., blocked by a network policy on ECS Fargate or EKS).
Fix: Use config.enc or environment variables instead. On EKS, use IAM Roles for Service Accounts (IRSA) with AWS_WEB_IDENTITY_TOKEN_FILE (not yet supported — use env vars with STS-assumed credentials).
C2S/SC2S: connection refused or timeout
Cause: The custom endpoint URL is unreachable from this network, or requires additional proxy/certificate configuration.
Fix: Verify the endpoint with curl -v --cacert /path/to/ca.pem https://<endpoint>/certauthorities?MaxResults=1. If the CA bundle needs to be trusted at the OS level, add it to the system trust store or use -insecure for testing only.