Gcp Audit Logs logo

Gcp Audit Logs

CommunityPopular
BagelHole
gcp-audit-logs

Configure GCP Cloud Audit Logs for compliance. Set up log routing and BigQuery analysis. Use when auditing GCP activity.

Overview

PublisherBagelHole
RepositoryDevOps-Security-Agent-Skills
Skill namegcp-audit-logs
Stars
1.1K
Forks
161
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by BagelHole on GitHub. Read the source before you install it.

Installation

Install the Gcp Audit Logs AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/BagelHole/DevOps-Security-Agent-Skills/tree/main/compliance/auditing/gcp-audit-logs
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/BagelHole/DevOps-Security-Agent-Skills.git /tmp/DevOps-Security-Agent-Skills
mkdir -p .claude/skills
cp -r /tmp/DevOps-Security-Agent-Skills/compliance/auditing/gcp-audit-logs .claude/skills/gcp-audit-logs
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Gcp Audit Logs in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Gcp Audit Logs on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Gcp Audit Logs is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

GCP Audit Logs

Audit GCP activity with Cloud Audit Logs for compliance, security investigation, and operational monitoring.

When to Use

  • Enabling organization-wide audit logging across GCP projects
  • Meeting compliance requirements for SOC 2, HIPAA, PCI DSS, or FedRAMP
  • Investigating unauthorized access or suspicious API activity
  • Setting up alerting on administrative and data access events
  • Exporting logs to BigQuery for long-term analysis and reporting

Audit Log Types

yaml
log_types:
  admin_activity:
    description: API calls that modify resource configuration or metadata
    enabled: Always (cannot be disabled)
    retention: 400 days (default)
    cost: No charge
    examples:
      - Creating or deleting VM instances
      - Changing IAM policies
      - Modifying firewall rules

  data_access:
    description: API calls that read resource configuration, metadata, or user data
    enabled: Must be explicitly enabled (except BigQuery)
    retention: 30 days (default)
    cost: Can be significant at high volume
    subtypes:
      ADMIN_READ: Read resource configuration/metadata
      DATA_READ: Read user-provided data
      DATA_WRITE: Write user-provided data

  system_event:
    description: Actions performed by GCP systems on behalf of resources
    enabled: Always (cannot be disabled)
    retention: 400 days (default)
    cost: No charge
    examples:
      - Live migration of VM instances
      - Automatic scaling events

  policy_denied:
    description: Actions denied by VPC Service Controls or organization policies
    enabled: Always (cannot be disabled)
    retention: 400 days (default)
    cost: No charge

Enable Data Access Logs for an Organization

bash
# Get current org IAM policy
gcloud organizations get-iam-policy ORG_ID --format=json > org-policy.json

# Add audit config to org-policy.json:
# {
#   "auditConfigs": [
#     {
#       "service": "allServices",
#       "auditLogConfigs": [
#         {"logType": "ADMIN_READ"},
#         {"logType": "DATA_READ"},
#         {"logType": "DATA_WRITE"}
#       ]
#     }
#   ],
#   ...existing bindings...
# }

# Apply the updated policy
gcloud organizations set-iam-policy ORG_ID org-policy.json

# Enable data access logs for specific services at project level
gcloud projects get-iam-policy PROJECT_ID --format=json > project-policy.json

# Example: enable only for Cloud Storage and BigQuery
# {
#   "auditConfigs": [
#     {
#       "service": "storage.googleapis.com",
#       "auditLogConfigs": [
#         {"logType": "DATA_READ"},
#         {"logType": "DATA_WRITE"}
#       ]
#     },
#     {
#       "service": "bigquery.googleapis.com",
#       "auditLogConfigs": [
#         {"logType": "DATA_READ"},
#         {"logType": "DATA_WRITE"}
#       ]
#     }
#   ]
# }

gcloud projects set-iam-policy PROJECT_ID project-policy.json

Configure Log Sinks for Export

bash
# Create BigQuery dataset for audit log export
bq mk --dataset \
  --description "Audit log export" \
  --default_table_expiration 0 \
  --location US \
  PROJECT_ID:audit_logs

# Create organization-level log sink to BigQuery
gcloud logging sinks create org-audit-bigquery \
  bigquery.googleapis.com/projects/PROJECT_ID/datasets/audit_logs \
  --organization=ORG_ID \
  --include-children \
  --log-filter='logName:"cloudaudit.googleapis.com"'

# Get the sink writer identity and grant BigQuery access
SINK_SA=$(gcloud logging sinks describe org-audit-bigquery \
  --organization=ORG_ID --format='value(writerIdentity)')

bq add-iam-policy-binding \
  --member="$SINK_SA" \
  --role="roles/bigquery.dataEditor" \
  PROJECT_ID:audit_logs

# Create Cloud Storage sink for long-term archive
gsutil mb -l US -b on gs://org-audit-logs-archive
gsutil retention set 7y gs://org-audit-logs-archive

gcloud logging sinks create org-audit-storage \
  storage.googleapis.com/org-audit-logs-archive \
  --organization=ORG_ID \
  --include-children \
  --log-filter='logName:"cloudaudit.googleapis.com"'

STORAGE_SA=$(gcloud logging sinks describe org-audit-storage \
  --organization=ORG_ID --format='value(writerIdentity)')

gsutil iam ch "$STORAGE_SA:objectCreator" gs://org-audit-logs-archive

# Create Pub/Sub sink for real-time streaming to SIEM
gcloud pubsub topics create audit-log-stream

gcloud logging sinks create org-audit-pubsub \
  pubsub.googleapis.com/projects/PROJECT_ID/topics/audit-log-stream \
  --organization=ORG_ID \
  --include-children \
  --log-filter='logName:"cloudaudit.googleapis.com" AND (protoPayload.methodName:"delete" OR protoPayload.methodName:"setIamPolicy" OR severity>=WARNING)'

PUBSUB_SA=$(gcloud logging sinks describe org-audit-pubsub \
  --organization=ORG_ID --format='value(writerIdentity)')

gcloud pubsub topics add-iam-policy-binding audit-log-stream \
  --member="$PUBSUB_SA" \
  --role="roles/pubsub.publisher"

Logging Queries (Cloud Logging Explorer)

bash
# View admin activity logs for the last 24 hours
gcloud logging read 'logName:"cloudaudit.googleapis.com/activity"
  AND timestamp>="2024-01-01T00:00:00Z"' \
  --project=PROJECT_ID \
  --format=json \
  --limit=100

# Find IAM policy changes
gcloud logging read 'logName:"cloudaudit.googleapis.com/activity"
  AND protoPayload.methodName="SetIamPolicy"' \
  --project=PROJECT_ID \
  --freshness=7d

# Find resource deletions
gcloud logging read 'logName:"cloudaudit.googleapis.com/activity"
  AND protoPayload.methodName=~"delete"
  AND severity>=NOTICE' \
  --project=PROJECT_ID \
  --freshness=7d

# Data access audit log entries
gcloud logging read 'logName:"cloudaudit.googleapis.com/data_access"
  AND protoPayload.serviceName="storage.googleapis.com"
  AND protoPayload.methodName="storage.objects.get"' \
  --project=PROJECT_ID \
  --freshness=24h

# Failed authorization attempts
gcloud logging read 'logName:"cloudaudit.googleapis.com/policy"' \
  --project=PROJECT_ID \
  --freshness=7d

BigQuery Analysis Queries

sql
-- All destructive operations in the last 30 days
SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS principal,
  protopayload_auditlog.methodName AS method,
  protopayload_auditlog.resourceName AS resource,
  resource.labels.project_id AS project,
  protopayload_auditlog.status.code AS status_code,
  protopayload_auditlog.status.message AS status_message
FROM `project.audit_logs.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND protopayload_auditlog.methodName LIKE '%delete%'
ORDER BY timestamp DESC
LIMIT 500;

-- IAM policy changes across the organization
SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS changed_by,
  resource.labels.project_id AS project,
  protopayload_auditlog.resourceName AS resource,
  protopayload_auditlog.servicedata_v1_iam.policyDelta.bindingDeltas
FROM `project.audit_logs.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND protopayload_auditlog.methodName = 'SetIamPolicy'
ORDER BY timestamp DESC;

-- Activity per principal (detect anomalous usage)
SELECT
  protopayload_auditlog.authenticationInfo.principalEmail AS principal,
  COUNT(*) AS action_count,
  COUNT(DISTINCT protopayload_auditlog.methodName) AS unique_methods,
  COUNT(DISTINCT protopayload_auditlog.requestMetadata.callerIp) AS unique_ips,
  MIN(timestamp) AS first_activity,
  MAX(timestamp) AS last_activity
FROM `project.audit_logs.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
GROUP BY principal
ORDER BY action_count DESC
LIMIT 50;

-- Service account key creation events (security risk indicator)
SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS created_by,
  protopayload_auditlog.resourceName AS service_account,
  protopayload_auditlog.requestMetadata.callerIp AS source_ip
FROM `project.audit_logs.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY))
  AND protopayload_auditlog.methodName = 'google.iam.admin.v1.CreateServiceAccountKey'
ORDER BY timestamp DESC;

-- Data access patterns for sensitive Cloud Storage buckets
SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS accessor,
  protopayload_auditlog.resourceName AS object_path,
  protopayload_auditlog.methodName AS access_type,
  protopayload_auditlog.requestMetadata.callerIp AS source_ip
FROM `project.audit_logs.cloudaudit_googleapis_com_data_access_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND protopayload_auditlog.resourceName LIKE '%sensitive-bucket%'
ORDER BY timestamp DESC
LIMIT 1000;

-- Failed operations indicating permission issues
SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS principal,
  protopayload_auditlog.methodName AS method,
  protopayload_auditlog.status.code AS error_code,
  protopayload_auditlog.status.message AS error_message,
  protopayload_auditlog.requestMetadata.callerIp AS source_ip
FROM `project.audit_logs.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND protopayload_auditlog.status.code != 0
ORDER BY timestamp DESC
LIMIT 500;

Alerting Policies

bash
# Alert on service account key creation
gcloud alpha monitoring policies create \
  --display-name="SA Key Created" \
  --condition-display-name="Service Account Key Creation" \
  --condition-filter='resource.type="audited_resource" AND protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"' \
  --condition-threshold-value=0 \
  --condition-threshold-comparison=COMPARISON_GT \
  --condition-threshold-duration=0s \
  --notification-channels=projects/PROJECT_ID/notificationChannels/CHANNEL_ID \
  --combiner=OR

# Create a log-based metric for IAM changes
gcloud logging metrics create iam-policy-changes \
  --description="Count of IAM policy changes" \
  --log-filter='logName:"cloudaudit.googleapis.com/activity" AND protoPayload.methodName="SetIamPolicy"'

# Create alerting policy using the log-based metric
gcloud alpha monitoring policies create \
  --display-name="IAM Policy Changes" \
  --condition-display-name="IAM Changes Detected" \
  --condition-filter='metric.type="logging.googleapis.com/user/iam-policy-changes"' \
  --condition-threshold-value=0 \
  --condition-threshold-comparison=COMPARISON_GT \
  --condition-threshold-duration=0s \
  --notification-channels=projects/PROJECT_ID/notificationChannels/CHANNEL_ID

# Create log-based metric for firewall changes
gcloud logging metrics create firewall-rule-changes \
  --description="Count of firewall rule changes" \
  --log-filter='logName:"cloudaudit.googleapis.com/activity"
    AND (protoPayload.methodName="v1.compute.firewalls.insert"
    OR protoPayload.methodName="v1.compute.firewalls.delete"
    OR protoPayload.methodName="v1.compute.firewalls.patch")'

# Create log-based metric for VPC network changes
gcloud logging metrics create vpc-network-changes \
  --description="Count of VPC network changes" \
  --log-filter='logName:"cloudaudit.googleapis.com/activity"
    AND resource.type="gce_network"
    AND (protoPayload.methodName=~"insert$" OR protoPayload.methodName=~"delete$")'

Terraform Configuration

hcl
# Organization-level audit log sink to BigQuery
resource "google_logging_organization_sink" "audit_bigquery" {
  name             = "org-audit-bigquery"
  org_id           = var.org_id
  destination      = "bigquery.googleapis.com/projects/${var.project_id}/datasets/${google_bigquery_dataset.audit_logs.dataset_id}"
  filter           = "logName:\"cloudaudit.googleapis.com\""
  include_children = true

  bigquery_options {
    use_partitioned_tables = true
  }
}

resource "google_bigquery_dataset" "audit_logs" {
  dataset_id    = "audit_logs"
  project       = var.project_id
  location      = "US"
  description   = "Organization audit log export"

  default_table_expiration_ms = null  # No auto-expiry

  access {
    role          = "WRITER"
    user_by_email = google_logging_organization_sink.audit_bigquery.writer_identity
  }

  access {
    role          = "READER"
    group_by_email = "security-auditors@example.com"
  }
}

# Retention bucket with bucket lock
resource "google_storage_bucket" "audit_archive" {
  name          = "org-audit-logs-archive"
  location      = "US"
  force_destroy = false
  project       = var.project_id

  uniform_bucket_level_access = true

  retention_policy {
    is_locked        = true
    retention_period = 220752000  # 7 years in seconds
  }

  lifecycle_rule {
    condition {
      age = 90
    }
    action {
      type          = "SetStorageClass"
      storage_class = "COLDLINE"
    }
  }
}

# Log-based alerting
resource "google_logging_metric" "iam_changes" {
  name    = "iam-policy-changes"
  project = var.project_id
  filter  = "logName:\"cloudaudit.googleapis.com/activity\" AND protoPayload.methodName=\"SetIamPolicy\""

  metric_descriptor {
    metric_kind = "DELTA"
    value_type  = "INT64"
  }
}

resource "google_monitoring_alert_policy" "iam_changes" {
  display_name = "IAM Policy Changes Detected"
  project      = var.project_id
  combiner     = "OR"

  conditions {
    display_name = "IAM policy change count"
    condition_threshold {
      filter          = "metric.type=\"logging.googleapis.com/user/iam-policy-changes\" AND resource.type=\"global\""
      comparison      = "COMPARISON_GT"
      threshold_value = 0
      duration        = "0s"
    }
  }

  notification_channels = [var.notification_channel_id]
}

Setup Checklist

yaml
gcp_audit_logs_checklist:
  log_enablement:
    - [ ] Admin activity logs verified active (always on)
    - [ ] Data access logs enabled for sensitive services
    - [ ] Data access exemptions configured to exclude high-volume, low-risk operations
    - [ ] System event logs verified active (always on)

  log_routing:
    - [ ] Organization-level sink to BigQuery for analysis
    - [ ] Organization-level sink to Cloud Storage for long-term archive
    - [ ] Pub/Sub sink for real-time SIEM streaming (high severity events)
    - [ ] Sink writer identities granted appropriate destination permissions
    - [ ] Inclusion filters verified to capture all audit log types

  storage_and_retention:
    - [ ] BigQuery dataset created with appropriate access controls
    - [ ] Cloud Storage bucket with retention policy and bucket lock
    - [ ] Storage class lifecycle rules configured (Standard to Coldline)
    - [ ] Default log retention in Cloud Logging extended if needed

  alerting:
    - [ ] Notification channels configured (email, PagerDuty, Slack)
    - [ ] Log-based metric for IAM policy changes
    - [ ] Log-based metric for firewall rule changes
    - [ ] Log-based metric for service account key creation
    - [ ] Alert policy for each critical metric
    - [ ] Alert notification tested end-to-end

  access_control:
    - [ ] Logging Admin role restricted to security team
    - [ ] BigQuery dataset read access granted to auditors only
    - [ ] Storage bucket access restricted with IAM
    - [ ] Sink configuration changes monitored via admin activity logs

Best Practices

  • Enable data access logs selectively on sensitive services to control cost and volume
  • Use organization-level sinks with include-children to capture all projects automatically
  • Export to BigQuery with partitioned tables for efficient querying over large time ranges
  • Archive to Cloud Storage with bucket lock and retention policies for immutable long-term storage
  • Create log-based metrics and alerting policies for high-severity events
  • Stream critical audit events via Pub/Sub to SIEM for real-time correlation
  • Apply exemptions to exclude high-volume read-only service accounts from data access logs
  • Restrict access to audit log sinks and destinations with least-privilege IAM bindings
  • Regularly run BigQuery analysis queries to detect anomalous patterns and generate compliance reports
  • Monitor log sink health and delivery latency to ensure continuous audit coverage

Frequently asked questions

What does the Gcp Audit Logs AI skill do?

Configure GCP Cloud Audit Logs for compliance. Set up log routing and BigQuery analysis. Use when auditing GCP activity.

Why use Gcp Audit Logs on TypingMind?

Because you install it once and use it with any model. Gcp Audit Logs is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Gcp Audit Logs in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/BagelHole/DevOps-Security-Agent-Skills/tree/main/compliance/auditing/gcp-audit-logs. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Gcp Audit Logs?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Gcp Audit Logs?

As many as you like. As long as a model supports skills, you can use Gcp Audit Logs with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Gcp Audit Logs AI skill free?

Yes. It is published on GitHub by BagelHole under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇