Skip to content
← AI in operationsStudy 10L3 (deterministic parser AST gates, SQL provenance contracts, and controlled redaction benchmarks)

Implementing ISO/IEC 42001 Annex A.4 and A.7: tool sandboxing, data quality, and egress redaction

Published
Data
53 MCP tools, 14 RAG connectors, 4.31M indexed chunks, 37 monitored data pipelines, 323 replayed tool outputs
Figures
4

The claim

When an organization connects an AI agent to internal databases and logs, governance moves from policy documents to infrastructure boundaries. In ISO/IEC 42001 (2023), two Annex A domains govern this layer. Annex A.4 (5 controls, A.4.2 to A.4.6) covers tooling and compute resources. Annex A.7 (5 controls, A.7.2 to A.7.6), paired with ISO/IEC 5259-1 (2024) to 5259-5 (2025) and EU AI Act Articles 10 and 15, covers data provenance, quality, and preparation.

Standard software guards often fail silently on agent workloads. If a SQL tool checks queries with regular expressions, a prompt injection or model error can still read local files or environment secrets. If a retrieval pipeline only checks job exit codes, an unrecorded model change can leave 99.12% of vectors (2,128,771 of 2,147,651) in the wrong space. Naive word-boundary regexes miss 81.8% of compound secret keys (27 of 33). Conversely, unfiltered cloud data-loss detectors falsely mask 100.0% of technical identifiers (18 of 18).

This report is Part 2 of our ISO/IEC 42001 (2023) series (Part 1). It details three production controls across 53 agent tools, 14 retrieval connectors (4.31M chunks), and 4 output paths.

First, we parse every agent query through the database engine's own C++ syntax tree (3 sandbox layers) and enforce 7 read-only confinement layers in PostgreSQL. Second, we apply ISO/IEC 5259-1 (2024) data quality rules across 37 monitored pipelines, combining quality floors (0.4), vector count checks, and BLAKE3 hashes. Third, we pair 33 redaction rules with a 32-character context filter and a 29.1 ms local firewall, reaching 99.4% recall across 323 tool outputs.

Four technical controls to deploy first

  1. Validate agent SQL with the database engine's own parser, then lock the configuration. Regular expressions on read_parquet(...) do not block read_csv, read_text, or getenv. Parse every query into a serialized abstract syntax tree (AST), allow only approved table functions and directory prefixes (3 prefixes), and run SET lock_configuration = true.
  2. Stamp every vector row with its embedding model, version, and BLAKE3 content hash. A green cron job does not prove retrieval integrity (Breck et al., 2019). Recording model provenance and checking batch vector counts on every write prevents silent vector-space drift across millions of rows.
  3. Remove leading word-boundary anchors (\b) from secret-key patterns. Standard \b(password|secret)\b patterns miss 27 of 33 (81.8%) camelCase and prefixed keys in logs and command lines. Match secret suffixes without a leading word boundary while exempting file-pointer keys.
  4. Filter cloud DLP detections against a 32-character technical context window. Default cloud detectors mistake software versions for IP addresses and transaction IDs or backup timestamps for phone numbers (18 of 18 masked). Reclassify matches adjacent to technical keywords (uuid, rpc, txn, or path slashes) so domain identifiers survive intact (0 of 18 lost).

Annex A.4.4 and A.4.5: sandboxing agent SQL tools and archive extraction

Annex A.4.4 of ISO/IEC 42001 (2023) and EU AI Act Article 15(5) require resilience against prompt injection and confidentiality attacks. An agent's analytical tools must therefore enforce least privilege at the parser and kernel boundaries.

1. The 3-layer C++ AST SQL sandbox

When an AI agent queries a columnar lakehouse (such as DuckDB over Parquet), teams often validate paths inside read_parquet(...) with a regular expression. Auditing that pattern showed that an adversarial or hallucinated query can bypass regex checks by calling other table functions (read_csv('/etc/passwd'), read_text(...), glob('*'), or duckdb_secrets()).

To close that class of escapes in any SQL-backed agent tool, we implemented a 3-layer defense-in-depth sandbox.

-- Layer 3 engine lockdown executed before any agent SQL statement:
SET allowed_directories = ['/cases', '/var/data/diagnostic-artifacts', '/mnt/diagnostic-artifacts'];
SET enable_external_access = false;
SET autoinstall_known_extensions = false;
SET autoload_known_extensions = false;
SET lock_configuration = true;
  • Layer 1 (Lexical pre-screen). The validator rejects queries with more than 1 semicolon, strips string literals and comments, and requires a SELECT, WITH, or DESCRIBE prefix. It blocks 15 DDL, DML, and administrative tokens (attach, call, copy, create, delete, detach, drop, insert, install, load, merge, pragma, truncate, update, vacuum).
  • Layer 2 (Authoritative C++ syntax-tree walk). The validator parses the SQL using the database engine's own C++ parser via duckdb.extract_statements() and SELECT json_serialize_sql(?). Walking the serialized JSON AST verifies five rules. First, it requires exactly 1 SELECT statement. Second, every table source must be a declared CTE or 1 of 2 allowed Parquet functions (read_parquet or parquet_scan). Third, every file argument must be a constant string literal under 1 of 3 approved directory prefixes. Fourth, 0 .. path-traversal segments are permitted. Fifth, 3 secret-inspection functions (getenv, current_setting, which_secret) and all other table functions are rejected.
  • Layer 3 (Engine configuration lock and resource caps). Before executing the verified query, the session runs the 5 lockdown statements above. Once SET lock_configuration = true runs, no subsequent SQL expression can enable external access or load extensions. Each query is capped at 2,000 rows, 2 MiB of output text, and 5,000 Parquet files per glob. Runtime is capped at 270 to 300 seconds, with 512 MB across 2 threads on in-process workers.

Panel A: adversarial and hallucinated SQL query classes blocked by the legacy regex check vs the 3-layer DuckDB C++ AST sandbox. Panel B: defense-in-depth check counts across MCP allowlists, PostgreSQL read-only roles, DuckDB, and archive extraction.

2. Seven-layer PostgreSQL confinement, tool allowlists, and archive guards

We paired the columnar AST sandbox with three additional Annex A.4.4 and A.4.5 resource controls:

  1. Seven-layer relational database confinement. Agent queries to PostgreSQL connect through a dedicated read-only role with default_transaction_read_only = on. Every call runs inside an explicit read-only transaction and blocks access to raw embedding tables. It also enforces a 30-token blocklist (pg_sleep*, set_config, pg_read_file, dblink*) and caps output at 500 rows and 30 to 60 seconds.
  2. Per-agent tool allowlists and call budgets. Rather than exposing all 53 MCP tools to every background workflow, our intake agent is restricted to an explicit 20-tool allowlist. Total tool calls are capped at 10 per run (3 search calls maximum), identical (tool, args) calls are deduplicated, and remote operations require human approval.
  3. Archive-bomb and sensitive-file blocking. When unpacking diagnostic archives on ephemeral batch VMs (64 to 2,000 GB dynamic disk), our extraction guard enforces 6 limits. It caps archives at 2,000,000 files, 16 GiB per file, and 64 GiB total (or 70% of dynamic disk). It also enforces a 7,200 to 21,600 second timeout, rejects all symbolic or hard links (0 allowed), and verifies target-directory containment. At ingestion, the pipeline also blocks 4 classes of sensitive artifacts: .sql database dumps, .hprof heap dumps, .pem private keys, and .env files.

Annex A.7 and ISO/IEC 5259: preventing silent data corruption in RAG pipelines

ISO/IEC 42001 (2023) Annex A.7 (A.7.2 to A.7.6) requires documented controls for data acquisition, quality, provenance, and preparation. Normative note Clause 3.25 points directly to the ISO/IEC 5259 series (ISO/IEC 5259-1 (2024) overview, 5259-2 (2024) quality measures, 5259-3 (2024) management requirements, 5259-4 (2024) process framework, and 5259-5 (2025) governance).

In production retrieval systems, standard job monitoring misses four classes of silent data corruption (Breck et al., 2019; Sculley et al., 2015).

silent data corruption mode what standard job monitoring showed what data-quality & provenance auditing found ISO/IEC 5259 & Annex A.7 control implemented
Vector-space drift (A.7.5) Ingestion jobs exited 0 with HTTP 200 An unrecorded model transition left 2,128,771 of 2,147,651 stored vectors (99.12%) in the prior embedding space Every vector row stamps embedding_model, embedding_version (2), BLAKE3 content hash, and ingestion timestamp
Upstream schema-field drift (A.7.3 / A.7.4) Issue-tracker sync logged 1,023 consecutive green runs Reading a standard field instead of a custom field overwrote the component column with NULL on 1,546 escalations (25 of 25 recent cases) Restored custom-field binding and added non-null column completeness checks alongside 37 SQL freshness contracts
Batch cardinality truncation (A.7.4 / A.7.6) HTTP 200 + zip() committed without error (report 05) Bare-string multimodal calls returned 1 vector per batch, dropping 85.1% to 96.9% of chunks Boundary assertion raises an exception whenever len(vectors) != len(texts)
Feedback-loop self-citation (A.7.2 / EU AI Act Art. 15(4)) Knowledge-base sync indexed all markdown files Later agent runs retrieved and cited prior AI-generated notes as ground truth Ingestion connector excludes AI-generated notes directories from indexing

Panel A: percentage of rows or vectors silently corrupted before vs after enforcing ISO/IEC 5259 provenance and schema checks. Panel B: pre-embedding heuristic chunk quality scorer multipliers and the 0.40 ingestion floor.

We operationalized ISO/IEC 5259-2 (2024) and 5259-4 (2024) across our 14 retrieval connectors (4.31M chunks). Prose chunks split at 1,000 characters (200 overlap) and code chunks split at 2,043 characters (100 overlap). Four deterministic gates govern ingestion.

  1. Pre-embedding chunk quality filter (floor = 0.4). Every candidate chunk starts at a score of 1.0. The scorer multiplies by 0.6 for under 15 words and 0.3 for under 7 words. It multiplies by 0.5 for a unique-word ratio below 0.25 and 0.4 for link density above 0.6. It subtracts 0.2 for each of 6 boilerplate patterns. Any chunk scoring below 0.4 is dropped before embedding.
  2. Boundary cardinality check and circuit breaker. Every embedding call asserts len(vectors) == len(texts) before writing to the store. A circuit breaker aborts a sync after 3 consecutive failed documents. It retries 429 or 503 API errors up to 5 times (10 to 120 s backoff).
  3. Cryptographic change detection (BLAKE3 and SHA-256). Every text chunk stores a BLAKE3 content hash. Every diagnostic archive stores its SHA-256 digest under a composite unique key, deduplicating fleet views from 10,700 to 10,213 rows. In customer disclosures, we distinguish incremental change detection (BLAKE3) from immutable storage locking.
  4. 37-source SQL freshness contracts. A PostgreSQL contract table monitors age / cadence, late thresholds, and stale thresholds across all 37 pipelines. Those 37 pipelines cover 10 relational, 14 RAG, 7 archive, and 6 trace feeds. Quiet event streams (such as incident paging) are evaluated by sync-job heartbeat rather than last-event age.

Annex A.7.6: two-layer egress redaction and the 29.1 ms monotonic firewall

Operational tickets and logs routinely contain database passwords, cloud API keys, and personal data. Under Annex A.7.6 (Data preparation), production enforces our 33-rule redactor plus regional Cloud DLP (technical_context keep-filter) across all 4 output paths. Deployment-workflow and configuration-code pull requests pin that Cloud Run enforcement across services.

1. Fixing the \b compound-secret leak and Cloud DLP identifier masking

Testing our redaction pipeline against production telemetry uncovered two opposite failure modes that affect any technical enterprise.

  • Why word-boundary \b regexes missed 81.8% of compound secrets (27 of 33). Standard 8-pattern secret redactors use \b(password|passwd|secret|token|...)\b. Because underscores and ASCII letters are word characters in regexes, a leading \b fails on prefixed or camelCase keys (ldapbindpasswd=, db_password=, clientSecret:). An offline regex-design scan of historical process-table snapshots (pidstat) uncovered 113,000 command-line password= or secret= arguments and 14,911 Java -pw VALUE flags. That scan motivated our 33-rule prefix-agnostic redactor (14 key rules and 19 value rules) before indexing or egress. We removed the inner \b boundary, added CLI flag parsers (--password, -pw, mysql -pVAL, cqlsh -p VAL while preserving psql -p <port>), and exempted file-pointer keys (vaultPasswordFile=/etc/x). Catch rate on the 33 compound secret patterns rose from 18.2% (6 of 33) to 100.0% (33 of 33).
  • Why unfiltered Cloud DLP masked 100.0% of technical identifiers (18 of 18). When we enabled regional Google Cloud DLP, its default PHONE_NUMBER, IP_ADDRESS, and ENCRYPTION_KEY detectors falsely masked 18 of 18 case-critical technical identifiers on a real incident. It turned release strings (v2.20.1) into [IP_ADDRESS], backup filenames (backup_26-10-11-07-00.tgz) and RPC call IDs into [PHONE_NUMBER], and replication stream IDs into [ENCRYPTION_KEY]. Under its 100-RPM quota, Cloud DLP also stalled for 57 to 59 seconds on 10.3% of calls.

We solved the identifier-masking defect by adding a deterministic 32-character technical_context keep-filter. Any PHONE_NUMBER, DATE_OF_BIRTH, CREDIT_CARD_NUMBER, or ENCRYPTION_KEY match containing a path slash or UUID is preserved as a technical identifier. Matches within 32 characters of a technical keyword (id, uuid, pid, tid, request, rpc, txn, op_id, term, tablet, peer, ht, priority) are preserved too. Across all 18 technical identifiers, false masking dropped from 100.0% (18 of 18) to 0.0% (0 of 18 lost).

Panel A: compound secret catch rate (n=33) and database technical identifier preservation (n=18) across legacy regex, raw Cloud DLP, and our 33-rule redactor + technical keep-filter. Panel B: two-stage monotonic firewall performance on 323 replayed MCP tool outputs.

2. Evaluating the two-stage monotonic privacy firewall at 29.1 ms

To eliminate the 10.3% Cloud DLP quota stalls, we evaluated a two-stage firewall. It pairs our 33 deterministic rules (Layer 3a) with a local 8-bit 4B model (Layer 3b). That local model runs at 29.1 ms median GPU latency (report 07). Both stages combine under a monotonic logical OR rule (Layer 3a OR Layer 3b).

Because the union is monotonic, the neural stage (Layer 3b) can add redactions on contextual secrets. It can never unmask a token matched by the 33 deterministic rules (Layer 3a). On our 77-item torture benchmark (49 secrets and PII, 28 technical IDs), the firewall caught 100.0% of secrets (49 of 49). It produced 0.0% false positives on the 18 database IDs. Evaluated across 323 replayed MCP tool outputs, the monotonic union achieved 99.4% recall at a 0.42% false-positive rate (F1 = 0.995) with 0.0% quota stalls.

Panel A: the 37 data, retrieval, archive, and LLM trace pipelines governed by SQL freshness contracts. Panel B: log-scale count of CLI and config secret patterns intercepted across process logs, Java flags, and benchmark corpora.

Verification gates and methodology checks

  • C++ AST SQL bypass suite. Tested multi-statement injections, CTE shadowing, read_csv, read_text, glob, duckdb_secrets, getenv, .. traversal, and runtime SET overrides against the 3-layer validator (100% blocked).
  • Vector-space provenance audit (2,147,651 vectors). Audited the vector store by model stamp, confirming that stamping embedding_model and embedding_version (2) plus strict batch-count checks prevents mixed-space indexing and silent truncation.
  • Technical identifier preservation check (18 technical IDs, 323 tool outputs). Verified that the 32-character technical_context keep-filter preserves 18 of 18 software versions, UUIDs, backup filenames, and RPC IDs while keeping secret recall at 100.0%.
  • Quantization floor on the local privacy gatekeeper. In report 07, 4-bit quantization flipped 5.4% to 8.7% of borderline safety decisions. Our local 29.1 ms firewall therefore enforces an 8-bit (Q8_0) minimum floor.

Tooling and data antipatterns rejected by our gates

  1. Regex-only SQL path validation on read_parquet(...). Replaced by the 3-layer C++ AST walk and SET lock_configuration = true.
  2. Judging data quality by cron job exit codes (0 errors). Replaced by ISO/IEC 5259-1 (2024) provenance stamps (BLAKE3 + embedding_model), non-null column checks, and 37 SQL freshness contracts.
  3. Word-boundary \b secret-key regexes (81.8% miss rate on compound keys). Replaced by 33 prefix-agnostic key and value rules and CLI flag parsers.
  4. Unfiltered Cloud DLP on technical telemetry (100.0% false masking on 18 technical IDs and 10.3% quota stalls). Fixed via the 32-character technical_context keep-filter and the 29.1 ms monotonic OR firewall.
  5. Allowing RAG connectors to index prior AI-generated case notes. Blocked by excluding AI-generated note directories from ingestion.

Pressure tests

Every finding was checked against the six standing fronts in Methods.

front what was tested result
Specification Regex SQL filtering vs native C++ AST serialization (json_serialize_sql) + lock_configuration Regex missed read_csv, glob, and duckdb_secrets; 3-layer AST + engine lock blocked 100% of non-Parquet sources
Aggregation Pipeline-level "green heartbeat" (1,023 sync runs) vs column-level completeness Heartbeat masked 1,546 nulled escalation rows; column-level check restored 100% component population
Adjustment coarseness Unfiltered Cloud DLP vs 32-character technical_context hotword keep-filter Unfiltered DLP masked 18 of 18 technical IDs; 32-char keep-filter reduced false masking to 0 of 18 (0.0%)
Prior work ML data validation (Breck et al., 2019), CACE entanglement (Sculley et al., 2015), and ISO/IEC 5259-1 (2024) Extended to vector-space model stamping (2.13M vectors), batch cardinality assertions, and monotonic DLP firewalls
Baseline sufficiency Deterministic 33-rule redactor alone (Layer 3a) vs monotonic union (n=323 outputs) Monotonic union guaranteed recall >= Layer 3a, reaching 99.4% recall and 0.42% FPR (F1 = 0.995) at 29.1 ms
Cross-sectional units Quiet event streams vs high-frequency ticket streams across 37 SQL freshness contracts Separated sync-pipeline heartbeat age from last-event age so quiet alert channels do not trigger false staleness

What this does not show

First, egress redaction at the tool layer (4 of 4 output paths) protects model and user outputs. Upstream storage defense-in-depth combines pre-embedding sanitization on high-sensitivity connectors with strict database role confinement (default_transaction_read_only = on and blocking direct SQL access to raw vector tables). Expanding pre-embedding sanitization across all 14 connectors is tracked on our governance roadmap.

Second, our heuristic chunk quality filter (floor = 0.4) scores prose and code chunks prior to vectorization. Multimodal attachments (screenshots and PDFs passed to multimodal models) bypass text chunking and are governed under a separate roadmap action.

Reproduce

All aggregate metrics in this report and its four figures are published in numbers.json, with SHA-256 file digests recorded in MANIFEST.md.

References

  • Breck, E., Polyzotis, N., Roy, S., Whang, S., & Zinkevich, M. (2019). Data Validation for Machine Learning. Proceedings of MLSys 2019.
  • Brundage, M., Avin, S., Wang, J., Belfield, H., Krueger, G., Hadfield, G., et al. (2020). Toward Trustworthy AI Development: Mechanisms for Supporting Verifiable Claims. arXiv preprint. arXiv.
  • CEN/CENELEC. (2026). EN 18286 (prEN 18286): Artificial Intelligence - Quality Management System for EU AI Act Regulatory Purposes. European Committee for Standardization.
  • European Parliament & Council of the European Union. (2024). Regulation (EU) 2024/1689 Laying Down Harmonised Rules on Artificial Intelligence (Artificial Intelligence Act). Official Journal of the European Union.
  • ISO/IEC. (2023). ISO/IEC 42001 (2023): Information Technology - Artificial Intelligence - Management System. International Organization for Standardization.
  • ISO/IEC. (2024). ISO/IEC 5259-1 (2024) to 5259-5 (2025): Artificial Intelligence - Data Quality for Analytics and Machine Learning (ML), Parts 1 to 5. International Organization for Standardization.
  • Mökander, J., Schuett, J., Kirk, H. R., & Floridi, L. (2023). Auditing Large Language Models: A Three-Layered Approach. AI and Ethics. DOI.
  • Sculley, D., Holt, G., Golovin, D., Davydov, E., Phillips, T., Ebner, D., et al. (2015). Hidden Technical Debt in Machine Learning Systems. Proceedings of NeurIPS 2015.