Skip to content
API Reference
Configuration

Audit Log Export

Export Keycard audit logs to your S3 bucket in OCSF format

Audit Log Export allows you to automatically export Keycard audit logs to your own AWS S3 bucket in OCSF (Open Cybersecurity Schema Framework) format. This enables integration with security information and event management (SIEM) tools, data warehouses, and custom analytics platforms.

Audit logs are exported in OCSF v1.7.0 format, an industry-standard schema for security events. Events include authentication, authorization, API operations, and secret management activities.

Files are delivered as Parquet files with the following characteristics:

  • Compression: Snappy compression
  • Partitioning: Files are organized by date
  • Naming: YYYY-MM-DD-HH-MM-SS-{uuid}.parquet
  • Delivery SLA: Events are delivered within one hour of occurrence

Files will be written to your bucket with this structure:

s3://your-bucket/[prefix/]YYYY-MM-DD-HH-MM-SS-{uuid}.parquet

Example:

s3://acme-keycard-audit-logs/keycard/audit_logs/2026-02-05-14-30-00-1b2e4543-cf21-49c2-9459-bdada803c24b.parquet

Before configuring audit log export, you’ll need:

  • An AWS S3 bucket in your AWS account
  • An IAM role with permissions for Keycard to write to your bucket
  1. Create an S3 bucket

    Create an S3 bucket in your AWS account where audit logs will be delivered:

    Terminal window
    aws s3api create-bucket \
    --bucket $BUCKET_NAME \
    --region us-east-1
  2. Enable bucket encryption

    Enable default encryption at rest for all objects:

    Terminal window
    aws s3api put-bucket-encryption \
    --bucket $BUCKET_NAME \
    --server-side-encryption-configuration '{
    "Rules": [{
    "ApplyServerSideEncryptionByDefault": {
    "SSEAlgorithm": "AES256"
    },
    "BucketKeyEnabled": true
    }]
    }'
  3. Block public access

    Enable S3 Block Public Access to prevent accidental public exposure:

    Terminal window
    aws s3api put-public-access-block \
    --bucket $BUCKET_NAME \
    --public-access-block-configuration \
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
  4. Enable bucket versioning

    Enable versioning to protect audit logs from accidental deletion or modification:

    Terminal window
    aws s3api put-bucket-versioning \
    --bucket $BUCKET_NAME \
    --versioning-configuration Status=Enabled
  5. Create IAM trust policy

    Create a file named trust-policy.json:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": "*"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
    "StringEquals": {
    "sts:ExternalId": "$EXTERNAL_ID"
    },
    "ForAnyValue:StringLike": {
    "aws:PrincipalOrgPaths": "o-c7hznpvsin/r-6n6x/ou-6n6x-bcvsfrlg/ou-6n6x-oox2udyt/*"
    }
    }
    }
    ]
    }
  6. Create the IAM role

    Terminal window
    aws iam create-role \
    --role-name KeycardAuditLogWriter \
    --assume-role-policy-document file://trust-policy.json
  7. Attach S3 permissions

    Create a file named permissions-policy.json:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "ListBucketForPrefix",
    "Effect": "Allow",
    "Action": ["s3:ListBucket"],
    "Resource": "arn:aws:s3:::$BUCKET_NAME"
    },
    {
    "Sid": "ReadWriteWithTLS",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
    "Resource": "arn:aws:s3:::$BUCKET_NAME/*",
    "Condition": {
    "Bool": {
    "aws:SecureTransport": "true"
    }
    }
    }
    ]
    }

    Replace $BUCKET_NAME with your actual bucket name.

    Attach the policy:

    Terminal window
    aws iam put-role-policy \
    --role-name KeycardAuditLogWriter \
    --policy-name S3WriteAccess \
    --policy-document file://permissions-policy.json

    Save the role ARN - you’ll need it for configuration:

    Terminal window
    aws iam get-role \
    --role-name KeycardAuditLogWriter \
    --query 'Role.Arn' \
    --output text
  8. (Optional) Upgrade to KMS encryption

    For enhanced security with customer-managed keys, you can upgrade from AES256 to KMS encryption.

    First, update your bucket encryption configuration to use KMS:

    Terminal window
    aws s3api put-bucket-encryption \
    --bucket $BUCKET_NAME \
    --server-side-encryption-configuration '{
    "Rules": [{
    "ApplyServerSideEncryptionByDefault": {
    "SSEAlgorithm": "aws:kms",
    "KMSMasterKeyID": "arn:aws:kms:us-east-1:$AWS_ACCOUNT_ID:key/$KMS_ID"
    },
    "BucketKeyEnabled": true
    }]
    }'

    Next, update the IAM role policy to grant KMS permissions. Create a file named kms-permissions-policy.json:

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "ListBucketForPrefix",
    "Effect": "Allow",
    "Action": ["s3:ListBucket"],
    "Resource": "arn:aws:s3:::$BUCKET_NAME"
    },
    {
    "Sid": "ReadWriteWithTLS",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
    "Resource": "arn:aws:s3:::$BUCKET_NAME/*",
    "Condition": {
    "Bool": {
    "aws:SecureTransport": "true"
    }
    }
    },
    {
    "Sid": "AllowKMSEncryption",
    "Effect": "Allow",
    "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
    "Resource": "arn:aws:kms:us-east-1:$AWS_ACCOUNT_ID:key/$KMS_ID"
    }
    ]
    }

    Replace:

    • $BUCKET_NAME with your bucket name (appears in 2 places)
    • $AWS_ACCOUNT_ID with your AWS account ID
    • $KMS_ID with your KMS key ID

    Update the IAM role policy:

    Terminal window
    aws iam put-role-policy \
    --role-name KeycardAuditLogWriter \
    --policy-name S3WriteAccess \
    --policy-document file://kms-permissions-policy.json

    Then grant the IAM role access to your KMS key by adding this statement to your KMS key policy:

    {
    "Sid": "AllowKeycardToEncrypt",
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::$AWS_ACCOUNT_ID:role/KeycardAuditLogWriter"
    },
    "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
    "Resource": "*"
    }

    Update your KMS key policy:

    Terminal window
    # Get current policy
    aws kms get-key-policy \
    --key-id $KMS_ID \
    --policy-name default \
    --output text > current-key-policy.json
    # Edit current-key-policy.json to add the AllowKeycardToEncrypt statement above to the "Statement" array
    # Update the key policy
    aws kms put-key-policy \
    --key-id $KMS_ID \
    --policy-name default \
    --policy file://current-key-policy.json

    Replace $AWS_ACCOUNT_ID and $KMS_ID with your actual AWS account ID and KMS key ID.

  9. Provide configuration to Keycard support

    Provide Keycard support with your configuration details:

    • S3 Bucket Name
    • S3 Bucket Region
    • IAM Role ARN
    • External ID - The External ID you generated and used in your IAM trust policy
    • S3 Key Prefix (optional): A prefix for organizing files, e.g., keycard/audit_logs/
    • KMS Key ARN (optional): Only if you upgraded to KMS encryption

    Keycard support will configure the export and notify you when it’s active.

  1. Check S3 bucket

    Confirm that Parquet files are being created in your bucket:

    Terminal window
    aws s3 ls s3://$BUCKET_NAME/keycard/audit_logs/
  2. Validate file contents

    Download and inspect a sample file:

    Terminal window
    # Install parquet-tools
    pip install parquet-tools
    # View file schema and sample data
    parquet-tools show s3://your-bucket/prefix/file.parquet
No files appearing in S3 bucket
  • Verify the IAM role trust policy includes the correct External ID provided by Keycard support
  • Confirm the IAM role has s3:PutObject permission on your bucket
  • Check with Keycard support that export is enabled for your organization
Access denied errors
  • Verify the IAM role has s3:PutObject and s3:ListBucket permissions
  • Ensure the External ID in the trust policy matches the value provided by Keycard support
  • If you upgraded to KMS encryption, confirm the KMS key policy grants access to the IAM role
  • Check that Block Public Access settings aren’t preventing the write operation
Files not readable by downstream systems
  • Confirm your system supports Parquet file format
  • Check that your system has appropriate AWS credentials to read from your S3 bucket
  • Verify file permissions and encryption settings are compatible with your system

Keycard delivers your audit logs to your S3 bucket using encrypted connections and authenticated access. It is your sole responsibility to ensure your S3 bucket is secure, this includes but is not limited to:

  • Maintaining appropriate S3 bucket policies and access controls
  • Managing encryption keys (if using KMS)
  • Controlling who can read audit logs from your bucket
  • Implementing lifecycle policies and retention requirements
  • Meeting your organization’s security and compliance standards

Keycard’s obligations are set out in your Master Services Agreement and Service Level Agreement. Once successful delivery of logs to your S3 bucket has been completed Keycard responsibility for the safekeeping of the data ends. All subsequent storage, access control, and data handling is your responsibility.