Self-Hosting Identity Activity Center
In this guide, you will set up the infrastructure required to enable the Identity Activity Center in Teleport's Identity Security product. Identity Activity Center allows you to centralize audit logs and access paths from various sources for enhanced visibility and management.
Teleport Identity Activity Center is a centralized data platform that enhances visibility, allows to search and analyze activity from both human and non-human identities across multiple data sources.
It provides a rich visualization layer that maps access policies across services such as AWS, GitHub, Okta, and Teleport with the real-time activity from those identities.
Built to assist security and operations teams, Identity Activity Center combines activities from the same identity across different platforms improving the correlation of identity-based events across platforms and expedites investigations. Through an intelligent alerting engine that detects irregularities in audit logs, emphasizes odd behavior, and describes the access levels each identity has across corporate services, it offers contextual insights during incident response.
Identity Activity Center is a feature of Teleport Identity Security product that is only available to Teleport Enterprise customers.
How it works
Teleport Identity Security uses an AWS SQS queue to publish and consume audit logs. When deployed in high-availability mode, Teleport Identity Security elects a leader that's responsible for consuming messages from the queue, converting and enhancing them with metadata such as location, and writing them as Parquet files in the long-term S3 bucket.
Amazon Athena powers a query engine in the Identity Activity Center. To specify the schema and retrieve data from Parquet files kept in the long-term S3 bucket, Amazon Athena makes use of an AWS Glue Table. With this configuration, audit logs can be efficiently queried and analyzed, leading to improved insights and simplified data management for identity security.
Prerequisites
- A running Teleport Enterprise cluster v18.0.0 or later.
- An updated Teleport Enterprise license file with Teleport Identity Security enabled.
- A PostgreSQL database server v14 or later.
- Access Graph needs a dedicated database to store its data.
The user that Teleport connects to the database with needs to be the owner of this database, or have similar broad permissions:
at least the
CREATE TABLE
privilege on thepublic
schema, and theCREATE SCHEMA
privilege. - Amazon RDS for PostgreSQL is supported.
- Access Graph needs a dedicated database to store its data.
The user that Teleport connects to the database with needs to be the owner of this database, or have similar broad permissions:
at least the
- A TLS certificate for the Access Graph service
- A running Access Graph node v1.28.0 or later. Check the Identity Security page for details on how to set up Access Graph.
The Identity Activity Center is currently supported only for self-hosted clusters. Teleport Enterprise Cloud support is planned for release later this year.
Step 1/4. Infrastructure setup
You can set up the required infrastructure to support the Identity Activity Center with the following Terraform script.
Terraform script
Below is a list of the required variables along with their descriptions, which are necessary for the Terraform script to execute.
- eu-central-1 is the name of the region where infrastructure should be created.
- example-sqs-queue is the name of the AWS SQS queue.
- example-sqs-dlq is the name of the AWS SQS dead-letter queue.
- example-kms-key is the name of the AWS KMS encryption key used to encrypt S3 bucket files and SQS messages.
- example-long-term-bucket is the long-term S3 bucket used to store the events.
- example-transient-bucket is the transient S3 bucket used to store temporary files such as query results and large files.
- example-db is the name of the AWS Glue database.
- example-table is the name of the AWS Glue table.
- example-workgroup is the name of the Amazon Athena Workgroup.
- aws-account-id is the AWS account id.
Define the variables using the script below or configure them in your Teleport IaC script.
cat > variables.auto.tfvars << EOF
aws_region = "eu-central-1"
iac_sqs_queue_name = "example-sqs-queue"
iac_sqs_dlq_name = "example-sqs-dlq"
iac_kms_key_alias = "example-kms-key"
iac_long_term_bucket_name = "example-long-term-bucket"
iac_transient_bucket_name = "example-transient-bucket"
iac_database_name = "example-db"
iac_table_name = "example-table"
iac_workgroup = "example-workgroup"
EOF
Execute the following Terraform script to create the required infrastructure.
variables.tf
variables.tf
file includes the description of the required Terraform variables.
variable "aws_region" {
description = "AWS region"
default = "us-west-2"
}
variable "iac_sqs_queue_name" {
description = "Name of the SQS queue used for Identity Activity Center."
}
variable "iac_sqs_dlq_name" {
description = "Name of the SQS Dead-Letter Queue used for handling unprocessable events"
}
variable "max_receive_count" {
description = "Number of times a message can be received before it is sent to the DLQ"
default = 20
}
variable "iac_kms_key_alias" {
description = "The alias of a custom KMS key"
}
variable "iac_long_term_bucket_name" {
description = "Name of the long term storage bucket used for storing audit logs"
}
variable "iac_transient_bucket_name" {
description = "Name of the transient storage bucket used for storing query results and large events payloads"
}
variable "iac_database_name" {
description = "Name of Glue database"
}
variable "iac_table_name" {
description = "Name of Glue table"
}
variable "iac_workgroup" {
description = "Name of Athena iac_workgroup"
}
variable "iac_workgroup_max_scanned_bytes_per_query" {
description = "Limit per query of max scanned bytes"
default = 21474836480 # 20GB
}
identity_activity_center.tf
identity_activity_center.tf
file includes the declaration of every resource
that Terraform will create and manage. This includes AWS KMS keys, AWS S3 Buckets
for transient and long-term storage, and AWS Glue table and database.
# ========================================
# Identity Activity Center Infrastructure
# ========================================
#
# This Terraform configuration provisions a comprehensive Identity Activity Center
# infrastructure on AWS designed to collect, store, and analyze identity-related
# events from various sources including AWS services, GitHub, Okta, and Teleport.
#
# Architecture Overview:
# 1. Event Collection: Events received via SQS queue
# 2. Processing: Events processed and stored in S3 buckets
# 3. Storage: Long-term storage in partitioned Parquet format
# 4. Analysis: Querying via Amazon Athena with Glue Data Catalog
#
# Security Features:
# - All data encrypted at rest using customer-managed KMS keys
# - S3 buckets with public access blocked
# - Versioning enabled for data protection
# - Dead letter queue for reliable message processing
#
# Data Partitioning Strategy:
# - tenant_id: Enables multi-tenant data separation
# - event_date: Daily partitions for efficient querying (4-year range)
# ========================================
# Provider Configuration
# ========================================
provider "aws" {
region = var.aws_region
}
# Get current AWS account information.
data "aws_caller_identity" "current" {}
# ========================================
# Encryption Infrastructure
# ========================================
# Customer-managed KMS key for encrypting all Identity Activity Center data
# This key is used across S3 buckets, SQS queues, and Athena query results
resource "aws_kms_key" "identity_activity_center_encryption_key" {
description = "KMS key for Athena audit log"
enable_key_rotation = true
}
# KMS key policy granting full access to the current AWS account
# In production, consider restricting to specific roles/users
resource "aws_kms_key_policy" "identity_activity_center_encryption_key_policy" {
key_id = aws_kms_key.identity_activity_center_encryption_key.id
policy = jsonencode({
Statement = [
{
Action = [
"kms:*"
]
Effect = "Allow"
Principal = {
AWS = data.aws_caller_identity.current.account_id
}
Resource = "*"
Sid = "Default Policy"
},
]
Version = "2012-10-17"
})
}
# Human-readable alias for the KMS key
resource "aws_kms_alias" "identity_activity_center_encryption_key_alias" {
name = "alias/${var.iac_kms_key_alias}"
target_key_id = aws_kms_key.identity_activity_center_encryption_key.key_id
}
# ========================================
# Message Queue Infrastructure
# ========================================
# Dead Letter Queue for messages that fail processing
# Retains messages for 7 days
# This provides time for troubleshooting failed message processing
resource "aws_sqs_queue" "identity_activity_center_queue_dlq" {
name = var.iac_sqs_dlq_name
# Encrypt messages using the Identity Activity Center KMS key
kms_master_key_id = aws_kms_key.identity_activity_center_encryption_key.arn
kms_data_key_reuse_period_seconds = 300 # 5 minutes - balances security and performance
# Extended retention for troubleshooting failed messages
message_retention_seconds = 604800 # 7 days
tags = {
Name = "Identity Activity Center DLQ"
Purpose = "Dead letter queue for failed identity event processing"
Component = "MessageQueue"
}
}
# Main SQS queue for receiving identity events from various sources
# Events include authentication attempts, access requests, and administrative actions
resource "aws_sqs_queue" "identity_activity_center_queue" {
name = var.iac_sqs_queue_name
# Encrypt all messages using customer-managed KMS key
kms_master_key_id = aws_kms_key.identity_activity_center_encryption_key.arn
kms_data_key_reuse_period_seconds = 300
# Configure dead letter queue for failed message processing
# Messages are moved to DLQ after max_receive_count failed processing attempts
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.identity_activity_center_queue_dlq.arn
maxReceiveCount = var.max_receive_count
})
tags = {
Name = "Identity Activity Center Main Queue"
Purpose = "Primary queue for identity event ingestion"
Component = "MessageQueue"
}
}
# ========================================
# Long-term Storage Infrastructure
# ========================================
# S3 bucket for permanent storage of processed identity events
# Data is stored in Parquet format with daily partitions by tenant_id and event_date
resource "aws_s3_bucket" "identity_activity_center_long_term_storage" {
bucket = var.iac_long_term_bucket_name
# Allow destruction for development - disable in production
force_destroy = true
# Object lock provides immutable storage for compliance requirements
# Recommended for production environments to prevent accidental deletion
object_lock_enabled = false
tags = {
Name = "Identity Activity Center Long-term Storage"
Purpose = "Permanent storage for processed identity events"
Component = "Storage"
DataType = "LongTerm"
}
}
# Enable KMS encryption for all objects in the long-term storage bucket
resource "aws_s3_bucket_server_side_encryption_configuration" "identity_activity_center_long_term_storage" {
bucket = aws_s3_bucket.identity_activity_center_long_term_storage.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.identity_activity_center_encryption_key.arn
sse_algorithm = "aws:kms"
}
# S3 Bucket Keys reduce KMS API calls and costs
bucket_key_enabled = true
}
}
# Enforce bucket owner control over all objects
resource "aws_s3_bucket_ownership_controls" "identity_activity_center_long_term_storage" {
bucket = aws_s3_bucket.identity_activity_center_long_term_storage.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}
# Enable versioning for data protection and compliance
resource "aws_s3_bucket_versioning" "identity_activity_center_long_term_storage" {
bucket = aws_s3_bucket.identity_activity_center_long_term_storage.id
versioning_configuration {
status = "Enabled"
}
}
# Block all public access to protect sensitive identity data
resource "aws_s3_bucket_public_access_block" "identity_activity_center_long_term_storage" {
bucket = aws_s3_bucket.identity_activity_center_long_term_storage.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# ========================================
# Transient Storage Infrastructure
# ========================================
# S3 bucket for temporary data storage including:
# - Athena query results
# - Processing intermediate files
# - Large files during processing
resource "aws_s3_bucket" "identity_activity_center_transient_storage" {
bucket = var.iac_transient_bucket_name
force_destroy = true
tags = {
Name = "Identity Activity Center Transient Storage"
Purpose = "Temporary storage for processing and query results"
Component = "Storage"
DataType = "Transient"
}
}
# S3 bucket deletes the files after 60 days.
resource "aws_s3_bucket_lifecycle_configuration" "identity_activity_center_transient_bucket_lifecycle_config" {
bucket = aws_s3_bucket.identity_activity_center_transient_storage.id
rule {
status = "Enabled"
id = "delete_after_60_days"
filter {}
expiration {
days = 60
}
}
}
# Apply same encryption configuration as long-term storage
resource "aws_s3_bucket_server_side_encryption_configuration" "identity_activity_center_transient_storage" {
bucket = aws_s3_bucket.identity_activity_center_transient_storage.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.identity_activity_center_encryption_key.arn
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_ownership_controls" "identity_activity_center_transient_storage" {
bucket = aws_s3_bucket.identity_activity_center_transient_storage.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}
resource "aws_s3_bucket_versioning" "identity_activity_center_transient_storage" {
bucket = aws_s3_bucket.identity_activity_center_transient_storage.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_public_access_block" "identity_activity_center_transient_storage" {
bucket = aws_s3_bucket.identity_activity_center_transient_storage.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# ========================================
# Data Catalog Infrastructure
# ========================================
# Glue database serves as a logical container for table metadata
# Used by Athena for querying identity event data
resource "aws_glue_catalog_database" "identity_activity_center_db" {
name = var.iac_database_name
description = "Database containing identity activity event tables for multi-tenant analytics"
}
# Glue table definition for identity events with comprehensive schema
# Supports data from multiple identity providers: AWS, GitHub, Okta, Teleport
resource "aws_glue_catalog_table" "identity_activity_center_table" {
name = var.iac_table_name
database_name = aws_glue_catalog_database.identity_activity_center_db.name
table_type = "EXTERNAL_TABLE"
description = "Identity activity events table with partition projection for efficient querying"
# Table parameters configure partition projection and storage format
parameters = {
"EXTERNAL" = "TRUE"
"classification" = "parquet"
"parquet.compression" = "SNAPPY"
# Partition projection automatically generates partition metadata
# Eliminates need for manual partition management
"projection.enabled" = "true"
# tenant_id projection - injected values for multi-tenant support
"projection.tenant_id.type" = "injected"
# event_date projection - daily partitions with 4-year range
"projection.event_date.type" = "date"
"projection.event_date.format" = "yyyy-MM-dd"
"projection.event_date.interval" = "1"
"projection.event_date.interval.unit" = "DAYS"
"projection.event_date.range" = "NOW-4YEARS,NOW"
# S3 location template for partitioned data
"storage.location.template" = format("s3://%s/data/$${tenant_id}/$${event_date}/", aws_s3_bucket.identity_activity_center_long_term_storage.bucket)
}
# Storage descriptor defines data format and location
storage_descriptor {
location = format("s3://%s/data/", aws_s3_bucket.identity_activity_center_long_term_storage.bucket)
input_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat"
output_format = "org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat"
ser_de_info {
name = "identity-events-parquet-serde"
serialization_library = "org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"
parameters = {
"serialization.format" = "1"
}
}
# Comprehensive schema for identity events from multiple sources
# Core identity and authentication fields
columns {
name = "event_source"
type = "string"
}
columns {
name = "identity"
type = "string"
}
columns {
name = "identity_kind"
type = "string"
}
columns {
name = "identity_id"
type = "string"
}
columns {
name = "token"
type = "string"
}
columns {
name = "action"
type = "string"
}
columns {
name = "origin"
type = "string"
}
columns {
name = "status"
type = "string"
}
columns {
name = "ip"
type = "string"
}
columns {
name = "city"
type = "string"
}
columns {
name = "country"
type = "string"
}
columns {
name = "region"
type = "string"
}
columns {
name = "latitude"
type = "double"
}
columns {
name = "longitude"
type = "double"
}
columns {
name = "target_resource"
type = "string"
}
columns {
name = "target_kind"
type = "string"
}
columns {
name = "target_location"
type = "string"
}
columns {
name = "target_id"
type = "string"
}
columns {
name = "user_agent"
type = "string"
}
columns {
name = "event_type"
type = "string"
}
columns {
name = "event_time"
type = "timestamp"
}
columns {
name = "uid"
type = "string"
}
columns {
name = "event_data"
type = "string"
}
columns {
name = "aws_account_id"
type = "string"
}
columns {
name = "aws_service"
type = "string"
}
columns {
name = "github_organization"
type = "string"
}
columns {
name = "github_repo"
type = "string"
}
columns {
name = "okta_org"
type = "string"
}
columns {
name = "teleport_cluster"
type = "string"
}
}
partition_keys {
name = "tenant_id"
type = "string"
}
partition_keys {
name = "event_date"
type = "date"
}
}
# ========================================
# Analytics Infrastructure
# ========================================
# Athena workgroup for managing query execution and cost controls
# Provides isolated environment for identity analytics queries
resource "aws_athena_workgroup" "identity_activity_center_workgroup" {
name = var.iac_workgroup
# Allow destruction for development environments
force_destroy = true
description = "Workgroup for Identity Activity Center analytics with cost controls and encryption"
configuration {
# Cost control - limit maximum data scanned per query
# Adjust based on expected query patterns and cost requirements
bytes_scanned_cutoff_per_query = var.iac_workgroup_max_scanned_bytes_per_query
# Use latest Athena engine for best performance and features
engine_version {
selected_engine_version = "Athena engine version 3"
}
# Configure encrypted storage for query results
result_configuration {
output_location = format("s3://%s/results/", aws_s3_bucket.identity_activity_center_transient_storage.bucket)
encryption_configuration {
encryption_option = "SSE_KMS"
kms_key_arn = aws_kms_key.identity_activity_center_encryption_key.arn
}
}
}
tags = {
Name = "Identity Activity Center Workgroup"
Purpose = "Analytics workgroup for identity event queries"
Component = "Analytics"
}
}
# ========================================
# Configuration Output
# ========================================
# Generate YAML configuration for applications consuming this infrastructure
# Provides all necessary connection details and endpoints
output "identity_activity_center_yaml" {
description = "YAML configuration for Identity Activity Center applications"
value = <<EOT
# Identity Activity Center Configuration
# Generated by Terraform - contains all necessary connection details
identity_activity_center:
# AWS Region where resources are deployed
region: ${var.aws_region}
# Athena database and table for querying identity events
database: ${var.iac_database_name}
table: '${var.iac_table_name}'
# S3 storage locations
s3: '${format("s3://%s/data", aws_s3_bucket.identity_activity_center_long_term_storage.bucket)}'
s3_results: '${format("s3://%s/results", aws_s3_bucket.identity_activity_center_transient_storage.bucket)}'
s3_large_files: '${format("s3://%s/large_files", aws_s3_bucket.identity_activity_center_transient_storage.bucket)}'
# SQS queue for event ingestion
sqs_queue_url: '${aws_sqs_queue.identity_activity_center_queue.url}'
# Athena workgroup for query execution
workgroup: '${aws_athena_workgroup.identity_activity_center_workgroup.name}'
# MaxMind GeoIP database path (configure based on your setup)
maxmind_geoip_city_db_path: './geo...'
EOT
}
# ========================================
# Additional Outputs for Integration
# ========================================
output "kms_key_arn" {
description = "ARN of the KMS key used for encryption"
value = aws_kms_key.identity_activity_center_encryption_key.arn
sensitive = false
}
output "sqs_queue_url" {
description = "URL of the main SQS queue for event ingestion"
value = aws_sqs_queue.identity_activity_center_queue.url
}
output "sqs_dlq_url" {
description = "URL of the dead letter queue"
value = aws_sqs_queue.identity_activity_center_queue_dlq.url
}
output "long_term_bucket_name" {
description = "Name of the S3 bucket for long-term storage"
value = aws_s3_bucket.identity_activity_center_long_term_storage.bucket
}
output "transient_bucket_name" {
description = "Name of the S3 bucket for transient storage"
value = aws_s3_bucket.identity_activity_center_transient_storage.bucket
}
output "database_name" {
description = "Name of the Glue database"
value = aws_glue_catalog_database.identity_activity_center_db.name
}
output "table_name" {
description = "Name of the Glue table"
value = aws_glue_catalog_table.identity_activity_center_table.name
}
output "athena_workgroup_name" {
description = "Name of the Athena workgroup"
value = aws_athena_workgroup.identity_activity_center_workgroup.name
}
policy.tf
policy.tf
includes the declaration of the AWS IAM policy that must
be attached to the AWS identity that the Identity Security service runs as,
enabling it to access the resources and execute queries.
# ========================================
# Identity Activity Center IAM Policy
# ========================================
#
# This Terraform configuration creates comprehensive IAM policies for the Identity
# Activity Center infrastructure. The policy grants least-privilege access to AWS
# services required for identity event processing, storage, and analytics.
#
# Policy Coverage:
# - S3 bucket and object operations for data storage and retrieval
# - SQS queue operations for event message processing
# - Athena and Glue operations for data analytics and querying
# - KMS operations for encryption/decryption of data
#
# Usage:
# This policy should be attached to IAM roles used by:
# - Lambda functions processing identity events
# - EC2 instances running data processing workloads
# - ECS/Fargate tasks handling identity analytics
# - Applications querying identity data via Athena
#
# Security Principles:
# - Least privilege access with specific resource ARNs
# - Separate permissions for different operation types
# - Resource-specific access patterns (e.g., data/* for objects)
# - KMS permissions limited to necessary operations
# ========================================
# Data Sources for Dynamic ARN Construction
# ========================================
# Get current AWS partition (aws, aws-gov, or aws-cn)
# Used for constructing ARNs that work across different AWS partitions
data "aws_partition" "current" {}
# Get current AWS region
# Used for constructing region-specific ARNs like Glue catalog
data "aws_region" "current" {}
# ========================================
# Identity Activity Center IAM Policy Document
# ========================================
# Comprehensive IAM policy document providing least-privilege access
# to all AWS services required by the Identity Activity Center
data "aws_iam_policy_document" "identity_activity_center_policy" {
# ========================================
# S3 Bucket-Level Permissions
# ========================================
# Allow listing and metadata operations on S3 buckets
# Required for multipart uploads, bucket discovery, and versioning operations
statement {
sid = "AllowListingMultipartUploads"
effect = "Allow"
actions = [
"s3:ListBucketMultipartUploads", # List incomplete multipart uploads
"s3:GetBucketLocation", # Get bucket region for cross-region operations
"s3:ListBucketVersions", # List object versions (versioning enabled)
"s3:ListBucket" # List objects in bucket
]
# Apply to both storage buckets used by Identity Activity Center
resources = [
aws_s3_bucket.identity_activity_center_transient_storage.arn, # Temporary storage
aws_s3_bucket.identity_activity_center_long_term_storage.arn, # Permanent storage
]
}
# ========================================
# S3 Object-Level Permissions
# ========================================
# Allow object operations within specific prefixes
# Supports large file uploads via multipart upload mechanism
statement {
sid = "AllowMultipartAndObjectAccess"
effect = "Allow"
actions = [
"s3:PutObject", # Upload new objects
"s3:ListMultipartUploadParts", # List parts of multipart upload
"s3:GetObjectVersion", # Get specific version of object
"s3:GetObject", # Download objects
"s3:DeleteObjectVersion", # Delete specific object version
"s3:DeleteObject", # Delete objects
"s3:AbortMultipartUpload" # Cancel incomplete multipart uploads
]
# Resource-specific access patterns for different data types
resources = [
# Long-term storage: processed identity events in Parquet format
# Organized by tenant_id and date partitions
format("%s/data/*", aws_s3_bucket.identity_activity_center_long_term_storage.arn),
# Transient storage: Athena query results
# Temporary files cleaned up by lifecycle policies
format("%s/results/*", aws_s3_bucket.identity_activity_center_transient_storage.arn),
# Transient storage: Large files during processing
# Intermediate files that exceed memory limits
format("%s/large_files/*", aws_s3_bucket.identity_activity_center_transient_storage.arn),
]
}
# ========================================
# SQS Queue Permissions
# ========================================
# Allow message operations on the Identity Activity Center queue
# Supports event ingestion workflow from various identity providers
statement {
sid = "AllowPublishReceiveSQS"
effect = "Allow"
actions = [
"sqs:ReceiveMessage", # Receive identity events from queue
"sqs:DeleteMessage", # Remove processed messages
"sqs:SendMessage" # Send new identity events to queue
]
# Apply only to the main Identity Activity Center queue
# Dead letter queue access not included (separate permissions if needed)
resources = [
aws_sqs_queue.identity_activity_center_queue.arn
]
}
# ========================================
# Athena and Glue Analytics Permissions
# ========================================
# Allow querying identity data via Athena and accessing Glue metadata
# Supports analytics workloads and reporting capabilities
statement {
sid = "AllowAthenaQuery"
effect = "Allow"
actions = [
# Glue Data Catalog operations
"glue:GetTable", # Get table schema and metadata
# Athena query operations
"athena:StartQueryExecution", # Execute SQL queries
"athena:GetQueryResults", # Retrieve query results
"athena:GetQueryExecution" # Get query status and metadata
]
resources = [
# Glue resources for table and database metadata
aws_glue_catalog_table.identity_activity_center_table.arn,
aws_glue_catalog_database.identity_activity_center_db.arn,
# Athena workgroup for query execution and cost control
aws_athena_workgroup.identity_activity_center_workgroup.arn,
# Glue Data Catalog (regional resource)
# Required for Athena to access table metadata
"arn:${data.aws_partition.current.partition}:glue:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:catalog",
]
}
# ========================================
# KMS Encryption Permissions
# ========================================
# Allow encryption and decryption operations for Identity Activity Center data
# Required for accessing encrypted S3 objects, SQS messages, and Athena results
statement {
sid = "AllowAthenaKMSUsage"
effect = "Allow"
actions = [
"kms:GenerateDataKey", # Generate data keys for encryption
"kms:Decrypt" # Decrypt data keys and objects
]
# Apply only to the Identity Activity Center KMS key
# Prevents access to other KMS keys in the account
resources = [
aws_kms_key.identity_activity_center_encryption_key.arn,
]
}
}
# ========================================
# Policy Output for External Use
# ========================================
# Output the complete IAM policy as JSON for use in IAM roles
# This policy can be attached to roles used by applications accessing
# the Identity Activity Center infrastructure
output "identity_activity_center_iam_policy" {
description = "Complete IAM policy JSON for Identity Activity Center access"
value = data.aws_iam_policy_document.identity_activity_center_policy.json
}
The Terraform script will output two variables:
identity_activity_center_iam_policy
: AWS IAM policy required for Identity Security to connect to AWS resources. Attach the policy to the Identity Security AWS IAM role.identity_activity_center_yaml
: YAML configuration to append to the Identity Security configuration or Helm chart values.
Step 2/4. Configure MaxMind GeoIP City database (optional)
MaxMind GeoIP database configuration is optional, but we do recommend it for geolocation tracking.
To enrich audit events with GeoIP details such as country, city, region, latitude, and longitude based on IP addresses, we strongly recommend using the MaxMind GeoIP City database.
MaxMind provides both free and paid versions of its GeoIP City database. The free version is less accurate and updated less frequently compared to the paid version. You can find instructions for downloading the free version or purchasing the paid version on the MaxMind Developer website.
- Self-hosted cluster
- Self-hosted cluster using Helm Chart
To configure enhanced location details for self-hosted clusters, upload the database file to the machine where Identity Security runs. You will specify its location in the config file below.
To configure enhanced location details for self-hosted clusters installed using the Helm Chart, first create the secret that contains the IP database:
$ kubectl create secret generic maxmind-geoip-city-db --from-file=GeoLite2-City.mmdb
Step 3/4. Modify Identity Security configuration
- Self-hosted cluster
- Self-hosted cluster using Helm Chart
To configure it for self-hosted clusters, update the Identity Security configuration and append the following section:
identity_activity_center:
region: eu-central-1
database: example-db
table: example-table
s3: s3://example-long-term-bucket/data/
s3_results: s3://example-transient-bucket/results/
s3_large_files: s3://example-transient-bucket/large_files
sqs_queue_url: https://sqs.eu-central-1.amazonaws.com/aws-account-id/example-sqs-queue
maxmind_geoip_city_db_path: /path/to/geoIp-city.mmdb # optional
To configure it for self-hosted clusters installed using the Helm Chart, update your Helm chart values with the following details:
# optional
volumes:
- name: maxmind-geoip-city-db
secret:
secretName: maxmind-geoip-city-db
optional: false
# optional
volumeMounts:
- name: maxmind-geoip-city-db
mountPath: "/etc/maxmindGeoIP/"
readOnly: true
identity_activity_center:
enabled: true
region: eu-central-1
database: example-db
table: example-table
s3: s3://example-long-term-bucket/data/
s3_results: s3://example-transient-bucket/results/
s3_large_files: s3://example-transient-bucket/large_files
sqs_queue_url: https://sqs.eu-central-1.amazonaws.com/aws-account-id/example-sqs-queue
maxmind_geoip_city_db_path: "/etc/maxmindGeoIP/GeoLite2-City.mmdb" # optional
Run helm upgrade
to re-deploy Identity Security.
Step 4/4. Restart Identity Security
- Self-hosted cluster
- Self-hosted cluster using Helm Chart
The final step is to restart the Identity Security docker process or restart the process so it can reload the latest configuration.
The final step is to wait for the Identity Security Deployment to complete the rollout of the new replicas.