Manage Data Protection - Barndoor Documentation
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
This guide manages your organization’s Data Control Center configuration in Terraform: the org-level switch, a detection engine ( Protection Profile), a custom detection type, allow-list entries that suppress false positives, and an enforcement policy rolled out safely with dry run. The whole flow is self-contained — no IDs need to be copied from the app.
Estimated time: 20–30 minutes. Complete Getting Started first. For the concepts, see the Data Control Center overview.
Before You Begin
- A configured
provider "barndoor"block (see Getting Started)
Step 1: Adopt the organization config
Data protection has one configuration object per organization, provisioned by the platform. The barndoor_dlp_org_config resource adopts that singleton rather than creating anything:
resource "barndoor_dlp_org_config" "this" {
enabled = true
# Observe-only mode: every policy records findings without acting.
global_dry_run = false
}
Reference: barndoor_dlp_org_config
Because it’s a singleton, terraform destroy doesn’t delete anything — it resets both settings to the platform defaults (enabled = true, global_dry_run = false) and drops the resource from state.
Step 2: Define a detection engine (Protection Profile)
A detection engine — a Protection Profile in the app — binds a detection provider to the data types it scans for. Enforcement policies reference engines, so at least one must exist. Manage it in Terraform, or look up one that was created in the portal:
New engine
Existing engine (data source)
resource "barndoor_dlp_detection_engine" "secrets" {
name = "Credential secrets"
provider_type = "builtin_secrets_regex"
enabled_detection_types = [\
"DETECTION_TYPE_AWS_ACCESS_KEY_ID",\
"DETECTION_TYPE_GITHUB_PAT",\
]
}
data "barndoor_dlp_detection_engine" "secrets" {
# Names are unique per provider_type; set provider_type (or use id)
# when one profile spans several engines.
name = "Credential secrets"
provider_type = "builtin_secrets_regex"
}
References: barndoor_dlp_detection_engine resource, data source
Engines are unique per (name, provider_type) — the same name across several provider types renders as one merged profile in the app. Deleting an engine that is the only one on an enforcement policy fails with an error naming the referencing policy.
Step 3: Define a custom detection type
Custom detection types extend the built-in detectors with organization-specific patterns — project codenames, internal ticket formats, customer ID shapes:
resource "barndoor_dlp_custom_detection_type" "codenames" {
name = "Project codenames"
description = "Internal project codenames that must not leave the organization"
patterns = [\
{ pattern = "(?i)project\\s+aurora", pattern_type = "PATTERN_TYPE_REGEX" },\
{ pattern = "AURORA-CLASSIFIED", pattern_type = "PATTERN_TYPE_LITERAL" },\
]
# Both default to *_MEDIUM when omitted.
default_severity = "DETECTION_SEVERITY_HIGH"
default_confidence = "DETECTION_CONFIDENCE_HIGH"
}
Reference: barndoor_dlp_custom_detection_type
Patterns are evaluated in order. Regex patterns use Rust regex syntax and are validated by the API — a pattern that doesn’t compile is rejected at apply time, not silently ignored. The platform assigns the type’s wire name (DETECTION_TYPE_CUSTOM_…), exposed as the detection_type attribute — that’s the value other data protection resources reference.
Step 4: Suppress false positives with allow-list entries
Allow-list entries stop known-safe values from being reported (and acted on) as findings:
# Scoped to specific detection types — including the custom one from Step 3.
resource "barndoor_dlp_allow_list_entry" "codename_docs_site" {
pattern = "aurora.docs.example.com"
pattern_type = "PATTERN_TYPE_LITERAL"
detection_types = [barndoor_dlp_custom_detection_type.codenames.detection_type]
reason = "Public documentation host, not a leak"
}
# Omit detection_types to suppress matches for every detection type.
resource "barndoor_dlp_allow_list_entry" "support_mailbox" {
pattern = "support@example.com"
pattern_type = "PATTERN_TYPE_LITERAL"
detection_types = ["DETECTION_TYPE_EMAIL"]
reason = "Shared support mailbox, not PII"
}
Reference: barndoor_dlp_allow_list_entry
The platform has no update operation for allow-list entries, so changing any attribute replaces the entry (delete + create). Plans will show this as a replacement — that’s expected.
Step 5: Enforce with a policy — dry run first
Enforcement policies decide what happens when a detection engine reports a finding. A policy targets exactly one lane: MCP traffic (tool inputs/outputs) or model-provider traffic (prompts/responses). Start in dry run — the policy evaluates and records findings in activity, but takes no action:
resource "barndoor_dlp_enforcement_policy" "block_secrets_in_prompts" {
name = "Block secrets in prompts"
action = "POLICY_ACTION_BLOCK"
provider_ids = ["openai"]
runtime_stage = "RUNTIME_STAGE_PROMPT"
# Roll out observing first; flip to false to enforce.
dry_run = true
detection_engine_ids = [barndoor_dlp_detection_engine.secrets.id]
}
And an MCP-lane example — tokenize PII in tool traffic for one group:
resource "barndoor_dlp_enforcement_policy" "tokenize_mcp_pii" {
name = "Tokenize PII on MCP traffic"
action = "POLICY_ACTION_TOKENIZE"
mcp_targets = [\
{ mcp_server_id = "*", direction = "BOTH" },\
]
principals = [\
{ principal_type = "GROUP", principal_id = "engineering" },\
]
dry_run = true
detection_engine_ids = [barndoor_dlp_detection_engine.secrets.id]
}
Reference: barndoor_dlp_enforcement_policy
The two lanes don’t mix. MCP_SERVER policies use mcp_targets with the RUNTIME_STAGE_TOOL_INPUT / RUNTIME_STAGE_TOOL_OUTPUT stages and may not set provider_ids or model_alias; MODEL_PROVIDER policies are the reverse, with RUNTIME_STAGE_PROMPT / RUNTIME_STAGE_RESPONSE. The API rejects mixed shapes. It also rejects (with a 422) any detection engine that doesn’t support the policy’s action.
Step 6: Flip to enforcement
Once dry-run findings in the activity view look right — expected matches, no false positives that an allow-list entry should cover — enforce by changing one line and re-applying:
dry_run = false
This is the code-review moment the dry-run pattern exists for: the diff that turns on enforcement is one visible line in a pull request.
There are two dry-run levers, and they compose: global_dry_run on the org config forces every policy to observe-only (useful during initial rollout of the whole system), while per-policy dry_run stages an individual policy. Enforcement happens only when both are off.
Complete example
Show Full configuration from this guide
resource "barndoor_dlp_org_config" "this" {
enabled = true
global_dry_run = false
}
resource "barndoor_dlp_detection_engine" "secrets" {
name = "Credential secrets"
provider_type = "builtin_secrets_regex"
enabled_detection_types = [\
"DETECTION_TYPE_AWS_ACCESS_KEY_ID",\
"DETECTION_TYPE_GITHUB_PAT",\
]
}
resource "barndoor_dlp_custom_detection_type" "codenames" {
name = "Project codenames"
description = "Internal project codenames that must not leave the organization"
default_severity = "DETECTION_SEVERITY_HIGH"
default_confidence = "DETECTION_CONFIDENCE_HIGH"
}
resource "barndoor_dlp_allow_list_entry" "codename_docs_site" {
pattern = "aurora.docs.example.com"
pattern_type = "PATTERN_TYPE_LITERAL"
detection_types = [barndoor_dlp_custom_detection_type.codenames.detection_type]
reason = "Public documentation host, not a leak"
}
resource "barndoor_dlp_enforcement_policy" "block_secrets_in_prompts" {
name = "Block secrets in prompts"
action = "POLICY_ACTION_BLOCK"
provider_ids = ["openai"]
runtime_stage = "RUNTIME_STAGE_PROMPT"
dry_run = true
detection_engine_ids = [barndoor_dlp_detection_engine.secrets.id]
}