← Nilou’s Notes

Safe by Design

Utsav Kanani, Head of Engineering · · 6 min read

Guardrails catch most bad behavior, and “most” is the problem. Three architecture decisions that secure our agentic AI platform before any guardrail is needed.

First, the news. Across AI has completed its SOC 2 Type 2 examination, along with an attestation against GDPR Article 5. The report is available to customers on request. A compliance audit tests the controls a company describes. This post is about the design decisions that made those controls possible.

Every AI vendor faces the same three fundamental questions now. First, do you train your models on our proprietary data? Second, can an autonomous agent access sensitive records that our own users cannot see? Third, what are the safety and accountability protocols when an agent acts on its own?

Standard security questionnaires do not yet cover these risks, leaving vendors to improvise. Common solutions, such as guardrail prompts, supervisor models, or output filters, function as a stack of patches. Each layer is merely a best effort attempt to catch the mistakes that the previous layer missed.

Every security reviewer knows what “most” means.

A better approach exists: architect the system so the risk is inherently contained. Security then stops depending on how a probabilistic component behaves on a given day.

Our CEO Nilou Salehi’s post Securing the Agentic Enterprise frames the shift from “who are you” to “why are you doing this”. This post is what that shift looks like at the architecture level and in production systems.

The core argument rests on three architectural pillars:

  1. Security at the Data Layer. A prompt cannot return a row the query never selected.
  2. The platform knows when to ask. Consequential or uncertain actions wait for a person; routine steps run within policy.
  3. Boring ingestion, on purpose. The data foundation is deterministic: the same input always builds the same graph.

The Foundation: Our Reasoning Graph

The Reasoning Graph is Across AI’s patented core architecture: a reasoning layer that turns what we ingest from a customer’s systems into entities, relationships, and derived conclusions, and preserves process context, state, decisions, and lineage while work runs. Agents reason over the graph and the content it has already indexed, and when a task needs live data, they reach it through MCP integrations that run under the same user-scoped permissions. Every conclusion carries the source records it came from, so when an agent tells you something, you can ask what it read and see the exact records.

The three decisions below all sit on top of that structure.

1. Security at the Data Layer

Most applications check permissions in application code. The query runs, results come back, and code filters out what the caller shouldn’t see. It works until some path through the code forgets to filter.

We evaluate access inside the database query itself. If you can’t access a record, the query never selects it. There is no result set to filter, and no moment where unauthorized rows sit in memory waiting on a check that might have a bug.

For AI, the consequence is simple. A user can try to talk the agent into showing a record they were never given, and the model may even try to comply. The record does not come back, because the lookup ran as that user. Prompt injection can change what a model attempts. It does not change what the database will select for that user.

This matters most for a product that reaches across several tools. Ask our agent in Slack or Teams about a record in your CRM, and enforcement happens once, underneath the model, instead of being re-implemented in every integration with slightly different bugs.

2. The platform knows when to ask

Some agent actions reach outside our platform, like updating a CRM record or sending a drafted message. The naive design is a human approval on every one of them. It reads well in a security review and fails in practice: bury people in confirmation prompts and they stop reading what they approve. Approval fatigue is how gates stop working.

We built a policy layer into the execution engine instead. Every action type carries a policy: run automatically, or ask first. Policies reflect how consequential and reversible an action is, and they are set with your organization, not decided by the model at runtime.

The Reasoning Graph is what makes that policy work in practice. Every action runs through it, and it holds the process context, state, and lineage of the work in flight, so the system knows which policy applies and how confident it is in its own read of the task. Routine, reversible steps, like matching a meeting to the right opportunity or keeping Salesforce fields current, run on their own. Consequential steps come to a person with exactly what the agent intends to do. When it isn’t sure, it stops and asks.

None of this is frozen on day one. Every decision you make at the gate becomes part of the graph, so the system’s proposals sharpen around where your organization draws its lines, and as trust grows, policies can loosen. That loosening is a choice people make, not something the model drifts into. And nothing disappears into the machine. Every action carries its full lineage, who it ran for, what it read, and why it acted, in an audit trail a security team can walk through. The model can propose and execute within policy. It cannot rewrite the policy.

The other boundary deserves equal precision, because this is where vendors overclaim. Approval gates apply to actions. If you ask a question or request a summary, the answer is advisory and nobody signs off before you read it. Anyone claiming every AI output in their product is human-reviewed is describing a product nobody would wait for.

3. Boring ingestion, on purpose

The least glamorous decision on this list. The pipelines that build the Reasoning Graph are classic ETL. They sync incrementally, they track the newest record already pulled so a re-run can’t duplicate or skip anything, and the transforms are deterministic. No model decides how a customer’s data foundation gets built.

That rigidity buys something specific. In a multi-step workflow, an error at ingestion doesn’t stay at ingestion. It propagates through every downstream step that reasons over the bad record. Agentic retrieval is flexible and occasionally wrong, and occasionally is too often for a foundation layer.

Live access is a different lane. Our integrations support MCP, so agents can reach current data the moment a task needs it rather than waiting for the next sync. Those calls run as the user, under the same query-layer permissions and the same audit trail as everything else. The split is deliberate: MCP for freshness where it helps, deterministic ETL for the memory the platform reasons over.

The fair objection: aggregation

Security teams push back on permission-centered arguments, and they should. Nilou makes a version of this argument in Securing the Agentic Enterprise that an agent can hold the right permissions and still do the wrong thing with them. For a system like ours, the sharpest version is aggregation: a hundred records that are individually harmless can add up to something sensitive, and all hundred might sit inside one user’s access.

What keeps this bounded is that in our system queries run as the user, so the agent combines only records that the user could have retrieved themselves. The AI compresses the effort. It doesn’t widen the access.

Compressed effort is still a change in risk, so the answer can’t be purely architectural. Every query an agent runs is attributable to the person it ran for, which makes unusual patterns reviewable. We would rather have that conversation with a security team than paper over it.

One more concession. No language model today is immune to prompt injection, including the ones we use. That is why these controls sit below the model instead of depending on it. Query-layer permissions bound what injected text can read. The approval gate still depends on a person reading what the model composed, and injected content can make a bad action look reasonable. We don’t claim otherwise.

A year under audit

From June 2025 through May 2026, Sensiba LLP examined the control environment these decisions live in, as part of our SOC 2 Type 2 report, alongside the GDPR attestation against Article 5. The examination sits alongside independent penetration testing and continuous control monitoring, so the evidence stays current between report cycles. A SOC 2 examination does not evaluate or validate the three design decisions above. What it establishes is that the access, change, and monitoring controls around this system were tested over a full year of real operation, including deployments, access reviews, and incidents. That is the part you shouldn’t have to take on faith.

First published in Nilou’s Notes on LinkedIn.

Get Nilou’s Notes

New posts on enterprise agents, memory, and security from Nilou Salehi and the Across team.

Subscribe on LinkedIn
across / new run start here

Let us help you get work done.