How to Stream HCP Vault Dedicated Audit Logs to Microsoft Sentinel

How to Stream HCP Vault Dedicated Audit Logs to Microsoft Sentinel

Enterprise Developer Platforms

What this stack enables: Full audit-log visibility for HCP Vault Dedicated clusters inside Microsoft Sentinel โ€” without leaving the Azure compliance perimeter.

Summary:

  • HCP Vault Dedicated emits audit events through a generic HTTP sink to an Azure Function App
  • The Function App validates requests, normalizes nested Vault fields into flat records, and authenticates via managed identity
  • Azure Monitor Logs Ingestion API routes normalized records into a custom Log Analytics table (HCPVaultAudit_CL) via a DCE-backed Data Collection Rule
  • Optional Microsoft Sentinel onboarding ships four starter scheduled analytics rules out of the box
  • The entire infrastructure is Terraform-managed โ€” one apply provisions everything from the resource group to Sentinel

Purpose

HCP Vault Dedicated audit logs capture every authentication, token creation, secret read, and policy evaluation in your cluster. Getting those logs into Sentinel closes the gap between your secrets infrastructure and your SOC โ€” enabling correlation with Azure Active Directory sign-ins, network flows, and resource changes in a single query surface.

Pre-requisites

Before you start, confirm all of the following:

  • HCP Vault Dedicated cluster at Essentials or Standard tier (Plus tier also supported)
  • HCP Admin role on the organization
  • Azure subscription with Owner or User Access Administrator permissions
  • Network path from the HCP cluster to your Azure ingestion endpoint over HTTPS (port 443)
  • Tooling installed locally: Terraform (1.5+), Azure CLI, Azure Functions Core Tools v4
  • Permissions to create a resource group, Log Analytics workspace, Function App (Consumption plan), and Data Collection Rule in the target Azure subscription

Steps

1. Clone the reference repository

git clone https://github.com/hashicorp/hcp-vault-audit-log-azure
cd hcp-vault-audit-log-azure

The repo contains the Terraform root module, the Function App source (func/), and helper scripts.

2. Authenticate to Azure

az login
az account set --subscription "<YOUR_SUBSCRIPTION_ID>"

3. Run the preflight check

bash scripts/preflight.sh

This validates that required Azure resource providers are registered (microsoft.operationalinsights, microsoft.insights, microsoft.web) and that your account has the minimum permissions before Terraform runs.

4. Configure Terraform variables

bash scripts/configure-terraform.sh

The script prompts for region, resource group name, workspace name, and a bearer token for the HTTP sink. It writes a terraform.tfvars file โ€” do not commit this file; it contains the bearer token in plaintext.

5. Initialize and apply Terraform

terraform init
terraform apply

Terraform provisions the following resources in a single pass:

ResourcePurpose
Resource group + Log Analytics workspaceContainer and storage for all log data
Custom table HCPVaultAudit_CLDestination for normalized Vault audit records
Data Collection Endpoint (DCE)HTTPS ingestion entry point
DCE-backed Data Collection Rule (DCR)Routes records from DCE to HCPVaultAudit_CL
Function App (Consumption plan)Validates, normalizes, and forwards audit events
System-assigned managed identityAuthenticates Function App to Azure Monitor โ€” granted Monitoring Metrics Publisher on the DCR only
Optional Sentinel workspace onboardingFour starter scheduled analytics rules

The managed identity is scoped to Monitoring Metrics Publisher on the DCR. No broader permissions are granted.

6. Publish the Function App

func azure functionapp publish <FUNCTION_APP_NAME>

Use the function app name from terraform output function_app_name.

7. Smoke-test the ingestion endpoint

bash scripts/smoke_test.sh

The script sends a sample audit payload to the Function App URL and polls Log Analytics for the record. Allow up to five minutes for first-time ingestion latency.

8. Retrieve output values

terraform output

Note function_app_url and bearer_token_secret_name โ€” you need both for the next step.

9. Configure the HCP Vault audit log stream

In the HCP portal:

  1. Navigate to your Vault Dedicated cluster
  2. Open Audit Logs โ†’ Enable Log Streaming
  3. Select Generic HTTP Sink
  4. Set POST as the HTTP method
  5. Set JSON as the encoding โ€” not NDJSON, not compressed (see The Trap below)
  6. Set Strategy = Bearer, paste the bearer token from Terraform output
  7. Enter the Function App URL as the sink endpoint
  8. Save and confirm the test event delivers successfully

10. Validate ingestion in Log Analytics

Run this KQL query in the Log Analytics workspace (allow up to 15 minutes after configuring the sink):

HCPVaultAudit_CL
| where TimeGenerated > ago(24h)
| summarize Events = count() by path
| order by Events desc
| take 20

A non-empty result confirms the full pipeline is operational.

The Trap

Using NDJSON or compressed encoding will silently break the pipeline.

The Function App expects a standard JSON array in the POST body. HCP Vaultโ€™s generic HTTP sink offers three encoding options โ€” JSON, NDJSON, and compressed. NDJSON delivers one JSON object per line with no wrapping array; the Function Appโ€™s JSON parser fails on the first line break and drops every event without returning an error to Vault. Compressed encoding adds a Content-Encoding: gzip header that the Consumption plan Function App does not decompress by default.

The result: Vault reports the sink as healthy (HTTP 200 from the Function Appโ€™s validation layer), Log Analytics shows zero rows, and there is no obvious error surface to diff against.

Fix: Always select standard JSON encoding in the HCP portal sink configuration. If you have existing events going missing, check HCPVaultAudit_CL | where TimeGenerated > ago(1h) | count before and after toggling encoding.

Security Notes

  • Protect Terraform state. The terraform.tfvars file and remote state may contain the bearer token in plaintext. Use a remote backend with encryption at rest (Azure Blob with customer-managed key, or Terraform Cloud).
  • Least-privilege identity. The managed identity holds only Monitoring Metrics Publisher on the DCR โ€” not Contributor or Log Analytics Contributor on the workspace.
  • Schema changes need care. Modifying the HCPVaultAudit_CL table schema after data is ingested may require a table rebuild. Test schema changes in a non-production workspace first.
  • One sink at a time. The generic HTTP sink supports a single destination. If you need to fan out to multiple SIEM targets, add a routing layer (Event Hub or Logic App) downstream of the Function App rather than duplicating the sink.

Cited References

The So What

HCP Vault Dedicated is a managed secrets backend, but audit logs are only useful if they live where your security team can query them. This stack closes that gap with a Terraform-managed pipeline that is deployable in under an hour and adds no ongoing operational overhead โ€” the Function App scales to zero on a Consumption plan, the managed identity requires no credential rotation, and certificate rotation is handled by the kubelet. If your compliance posture requires evidence of every secret access and policy evaluation, and your SOC runs on Sentinel, this is the reference architecture worth starting from.

Source: HashiCorp Blog

Content created with AI assistance and reviewed for accuracy.

๐Ÿ’ฌ

Join the conversation

Stack Insiders is our free community for readers who want to go deeper โ€” share resources, ask questions, and connect with others across every vertical we cover.

Join Stack Insiders →

Newsletter coming soon.

Curated digests across AI, biohacking, photography, travel, and more. Be the first to know when we launch.