Skip to content

Configuration API

Configuration options for Agent-Airlock.

AirlockConfig

from agent_airlock import AirlockConfig

Signature

@dataclass
class AirlockConfig:
    # Validation
    unknown_args: UnknownArgsMode = UnknownArgsMode.STRIP_AND_LOG
    strict_mode: bool = False  # deprecated, use unknown_args

    # Output Sanitization
    max_output_tokens: int = 5000
    max_output_chars: int = 20000
    mask_pii: bool = True
    mask_secrets: bool = True
    sanitize_output: bool = True
    withhold_unmaskable_output: bool = False
    pii_locales: list[str] = field(default_factory=list)
    strip_hidden_html: bool = False

    # Audit
    enable_audit_log: bool = True
    audit_log_path: Path = Path("airlock_audit.json")
    audit_otel_enabled: bool = False
    audit_otel_endpoint: str | None = None
    audit_include_args_hash: bool = True
    decision_log: DecisionLog | None = None  # V0.10.29
    output_trust_guard: ToolOutputTrustGuard | None = None  # V0.10.29

    # E2B Sandbox
    e2b_api_key: str | None = None
    sandbox_timeout: int = 60
    sandbox_pool_size: int = 2

    # Callbacks
    on_validation_error: Callable[[str, ValidationError], None] | None = None
    on_blocked: Callable[[str, str, dict], None] | None = None
    on_rate_limit: Callable[[str, int], None] | None = None

    # Security policies
    filesystem_policy: FilesystemPolicy | None = None
    network_policy: NetworkPolicy | None = None
    honeypot_config: HoneypotConfig | None = None
    capability_policy: CapabilityPolicy | None = None
    endpoint_policies: dict[str, EndpointPolicy] = field(default_factory=dict)
    anomaly_config: AnomalyDetectorConfig | None = None
    require_done_receipt: bool = False
    credential_scopes: dict[str, CredentialScope] = field(default_factory=dict)

    # Call-time checks (V0.10.27)
    expected_token_audience: str | None = None
    token_audience_mode: Literal["off", "warn", "deny"] = "warn"
    startup_hook_check: Literal["off", "warn", "deny"] = "off"
    startup_hook_allowlist: dict[str, str] = field(default_factory=dict)

Attributes

Validation

Attribute Type Default Description
unknown_args UnknownArgsMode STRIP_AND_LOG Arguments the function does not declare: BLOCK rejects the call, STRIP_AND_LOG drops them and logs a warning, STRIP_SILENT drops them without one
strict_mode bool False Deprecated; emits a DeprecationWarning. True maps to unknown_args=BLOCK

Output Sanitization

Attribute Type Default Description
sanitize_output bool True Enable output sanitization
withhold_unmaskable_output bool False Refuse (output_unreadable) a result whose detected secret or PII cannot be masked in place (a model, a dataclass, non-text MCP content)
mask_pii bool True Mask PII in outputs
mask_secrets bool True Mask secrets in outputs
pii_locales list[str] [] ["in"] adds the India PII types
strip_hidden_html bool False Remove the HTML a person cannot see (inline-styled out of view, hidden, comments) from a string result before it is masked. See Hidden HTML
max_output_chars int 20000 Truncate string results at this many characters; 0 means no limit
max_output_tokens int 5000 Deprecated, removal in v1.0.0: nothing has ever truncated on it (it is read from AIRLOCK_MAX_OUTPUT_TOKENS too); any other value warns

Each detected type is masked with its default strategy (see MaskingStrategy). AirlockConfig has no field for choosing a strategy or for picking individual types.

Audit

Attribute Type Default Description
enable_audit_log bool True Append JSON Lines audit records to audit_log_path
audit_log_path Path airlock_audit.json Audit log file, relative to the working directory; AIRLOCK_AUDIT_LOG_PATH replaces the default when no path is given in code or TOML
decision_log DecisionLog \| None None Hash-chained log each call's decision is written to before the tool runs, and its outcome after. A decision that cannot be written refuses the call. Set in code only. See Decision records
output_trust_guard ToolOutputTrustGuard \| None None Checks every result after masking, streamed values included. A flagged output is returned enveloped, refused as output_untrusted, or refused with the run halted (run_halted), as the guard's on_flag says; none is replaced by a placeholder. Set in code only. See Tool output trust

Sandbox

Attribute Type Default Description
e2b_api_key str \| None None E2B API key; the E2B_API_KEY env var is used when unset
sandbox_timeout int 60 Execution timeout in seconds
sandbox_pool_size int 2 Warm sandboxes kept ready

Callbacks

Attribute Type Default Description
on_validation_error Callable None Called on validation errors
on_blocked Callable None Called when calls are blocked
on_rate_limit Callable None Called on rate limit

Security Policies

Attribute Type Default Description
filesystem_policy FilesystemPolicy \| None None Validates path-like arguments
network_policy NetworkPolicy \| None None Egress control while the tool runs; what it covers is in The Network Airgap
honeypot_config HoneypotConfig \| None None Deception for blocked calls, e.g. fake success
capability_policy CapabilityPolicy \| None None Checked against @requires; a SecurityPolicy's own capability_policy takes precedence
endpoint_policies dict[str, EndpointPolicy] {} Per-tool URL rules
credential_scopes dict[str, CredentialScope] {} Per-tool scopes from [airlock.credentials]. Not applied by @Airlock: pass them to MCPProxyConfig(tool_scopes=config.credential_scopes)

Call-time checks

Attribute Type Default Description
expected_token_audience str \| None None This server's canonical resource URI. When set, every guarded call checks the aud claim of the claims the host put on its AirlockContext metadata under access_token_claims (CVE-2026-115413)
token_audience_mode "off" \| "warn" \| "deny" "warn" warn logs a wrong or missing audience and runs the call; deny refuses it
startup_hook_check "off" \| "warn" \| "deny" "off" Walks the interpreter's executable .pth lines and sitecustomize / usercustomize once per process; deny refuses every guarded call while one is not allowlisted
startup_hook_allowlist dict[str, str] {} {file name: sha256} of the startup hooks you know

A mode outside off / warn / deny, an audience that is not a resource URI and an allowlist entry that is not a file name and a SHA-256 digest each raise ValueError when the config is built. See Token audience and startup hooks.

audit_otel_enabled, audit_otel_endpoint, audit_include_args_hash, anomaly_config and require_done_receipt are accepted and stored, but nothing has ever read them. They are deprecated for removal in v1.0.0, and setting one to anything but its default emits a FutureWarning, shown by default, naming what to use instead: OTelAuditExporter for the audit settings, an AnomalyDetector for anomaly_config, and DoneReceiptGuard (or the no_false_success_defaults preset) for require_done_receipt. Until 0.10.19 they were stored without a word, although require_done_receipt's comment said it switched on a fail-closed guard.

Example

from agent_airlock import AirlockConfig, UnknownArgsMode

config = AirlockConfig(
    unknown_args=UnknownArgsMode.BLOCK,
    sanitize_output=True,
    mask_pii=True,
    mask_secrets=True,
    max_output_chars=10000,
)

MaskingStrategy

from agent_airlock import MaskingStrategy

Values

Value Example Input Example Output
FULL john@example.com [REDACTED]
PARTIAL john@example.com j***@example.com
TYPE_ONLY john@example.com [EMAIL]
HASH john@example.com [HMAC:3f9a8c2e1b7d4065] (keyed per request)

@Airlock uses a fixed default per type: FULL for SSN, password, private key and connection string, TYPE_ONLY for IFSC, PARTIAL for the rest. To choose, call the standalone sanitizer with a mask_config mapping. A type left out of the mapping is masked FULL:

from agent_airlock import MaskingStrategy, SensitiveDataType, sanitize_output

result = sanitize_output(
    "john@example.com",
    mask_config={SensitiveDataType.EMAIL: MaskingStrategy.TYPE_ONLY},
)
result.content  # "[EMAIL]"

SensitiveDataType

from agent_airlock import SensitiveDataType

Values

PII Types

Masked when mask_pii=True.

Value Description
EMAIL Email addresses
PHONE Phone numbers
SSN Social Security Numbers
CREDIT_CARD Credit card numbers (unbroken digits)
IP_ADDRESS IP addresses

India PII Types

Added when mask_pii=True and pii_locales=["in"].

Value Description
AADHAAR Aadhaar numbers (Verhoeff-checked)
PAN Permanent Account Numbers
UPI_ID UPI IDs
IFSC Bank IFSC codes
PERSONAL_NAME_DEVANAGARI Names in Devanagari script
INDIA_MOBILE Mobile numbers with a +91, 91 or 0 prefix

Secret Types

Masked when mask_secrets=True.

Value Description
API_KEY Known API key formats (OpenAI, Anthropic, Google, GitHub, Slack)
AWS_KEY AWS access keys
PASSWORD Password patterns
JWT JSON Web Tokens
CONNECTION_STRING Database URLs
PRIVATE_KEY Private key markers

Environment Variables

Only these are read. They are read when an AirlockConfig is built, and the first three override the constructor and the TOML file. @Airlock() with no config uses DEFAULT_CONFIG, which is built when agent_airlock is imported, so set them before the import.

Variable Config Attribute
AIRLOCK_UNKNOWN_ARGS unknown_args (block, strip_and_log or strip_silent)
AIRLOCK_MAX_OUTPUT_TOKENS max_output_tokens (deprecated, never applied)
AIRLOCK_STRICT_MODE strict_mode (deprecated; true maps to block, any other value to strip_and_log)
E2B_API_KEY e2b_api_key, when it is not set in code or TOML
AIRLOCK_AUDIT_LOG_PATH audit_log_path, when it is not set in code or TOML

Configuration File

Nothing loads airlock.toml automatically. Load it with AirlockConfig.from_toml("airlock.toml"), or AirlockConfig.from_toml_if_exists(), which returns the defaults when the file is missing. Keys go under [airlock]; unknown keys are logged and ignored.

[airlock]
unknown_args = "block"
sanitize_output = true
mask_pii = true
mask_secrets = true
max_output_chars = 10000
sandbox_timeout = 60

# Per-tool credential scopes, loaded into config.credential_scopes
[airlock.credentials.read_file]
required_scopes = ["fs:read"]
max_token_age_seconds = 600

Until 0.10.19 a file with an [airlock.credentials] section failed to load with a TypeError.