# What we cover with Security Watch and Agent Guard

> AI agent security, part 2 of 4. The risks from the first article, the controls we provide, and the gaps we still have to handle in each deployment.

- Canonical URL: https://shielda.ai/blog/security-watch-and-agent-guard/
- Published: 2026-11-04
- Author: Vasyl
- Reading time: 8 min read
- Tags: AI Agent Security, Open Source, Security Watch, Agent Guard
- Cover image: https://shielda.ai/blog/covers/security-watch-and-agent-guard.webp?v=editorial-1
- Cover description: An advisory passes through two read-only handoffs before an orange gate stops the route to production.

A critical advisory can lead to a production change, but the task investigating it may only have permission to read. In our delegation test, a support task could read one ticket. Passing it through operations and a deployment specialist still did not authorize a release.

That is where our two projects meet in the workflow we propose. [Security Watch](https://github.com/ShieldaAI/security-watch) helps establish which systems need attention and keeps the evidence behind that finding. [Agent Guard](https://github.com/ShieldaAI/agent-guard) checks what the resulting task may do. They are independent projects. The application joining them still has to decide who may authorize work and which operations the task needs.

[Part one](https://shielda.ai/blog/ai-agent-security-familiar-risks/) described the risks. Here we follow those risks through the controls available in the public releases, Watch `0.1.0-alpha.0` and Guard `0.1.0-alpha.2`. We ran local examples for inventory and delegation and inspected the published contracts for the other integrations. The examples are small and synthetic. They are useful for checking a particular guarantee, without establishing coverage across a production environment.

## A finding based on missing or old information

Security Watch compares a declared inventory with advisories and security news. It keeps source severity, applicability to that inventory and handling priority separate. Missing evidence can remain unknown instead of turning into an instruction to patch.

We gave one scan a fictional critical advisory for npm package `example-parser`, covering versions from 1.0.0 up to, but excluding, 1.3.0. Notifications were disabled.

- Production listed `1.2.0` in a fresh record. The bot marked it `affected`.
- Staging listed `1.3.0` in a fresh record. It was `not_affected` for this advisory.
- A record with no installed version stayed `unknown`.
- An older staging record also listed `1.3.0`, but its last update was twelve days old. It stayed `unknown`, with a separate stale-inventory finding.

The advisory remained critical in every case. Production needed someone to check the deployed package. The older staging record needed someone to verify the inventory. Asking both owners to patch would have lost that distinction. [Inventory test](https://shielda.ai/blog/examples/security-watch-and-agent-guard/inventory-freshness.mjs) · [Recorded results](https://shielda.ai/blog/examples/security-watch-and-agent-guard/inventory-freshness-results.json)

This covers part of the dependency risk from the first article. Watch follows configured sources and supported matching rules. It does not inspect what is actually running, prove that vulnerable code is reachable or apply a patch. Its optional news analysis can help with less structured reports, but supported version exclusions are currently limited to npm. Other ecosystems often remain uncertain. A finding can justify investigation without granting permission to change the system. [Coverage limits](https://github.com/ShieldaAI/security-watch/blob/abde870beb5058d8e82a071df11afb0ba29aecda/SECURITY.md#coverage-limitations)

## A read-only task borrowing someone else’s access

Agent Guard gives a task explicit grants for registered operations and resources. A child can retain or narrow those grants. A staging-only handoff must stay staging-only even if the original task and the specialist’s account both have production access. Descendant calls also count against ancestor budgets, so creating more workers does not create a fresh budget at each handoff.

We tested a support task that could read one ticket, delegated to operations and then to a specialist. Two harmless handlers counted ticket reads and deployments. The specialist read the ticket once, and the executor charged all three tasks. Preparing a production deployment returned `GRANT_DENIED`, with zero deployment effects. Trying to create a child with that wider grant returned `DELEGATION_DENIED`.

There was still a possible explanation for the zero. We might simply have wired up a deployment tool that never worked. A separate release task with the correct grant and approval ran that same handler once. The allowed control matters as much as the refusal. [Delegation test](https://shielda.ai/blog/examples/security-watch-and-agent-guard/delegated-task.mjs) · [Recorded results](https://shielda.ai/blog/examples/security-watch-and-agent-guard/delegated-task-results.json)

All three support-chain identities used one executor on one machine. An independent receiving service must check delegated authority itself. An unrestricted shell, raw SDK client or direct service credential would also provide a route around the mediated operations. Those routes have to be constrained by the host. [Authority and transport](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/packages/executor/README.md#authority-and-transport)

## An approval for something different

A task may have permission to deploy while a particular deployment still needs review. Guard preserves the prepared arguments and resolved resource, then binds approval to that action. It checks current authority and consumes approval before dispatch.

In the tests covered in [part four](https://shielda.ai/blog/agent-guard-permission-to-try-again/), changing the caller’s arguments after approval did not change the stored deployment. An approval for revision `r18` could not authorize `r19`, and a consumed action could not run again.

A changing target needs another check. Guard can carry the approved resource version, but the trusted adapter must compare it with the current version atomically with the operation. Otherwise the target can change between checking it and writing. The host also has to authenticate the person giving approval. Registering a tool does not supply either of those guarantees automatically.

## Instructions arriving through content, memory and tools

For prompt injection, Guard assumes the model may follow hostile instructions. It checks the requested operation before its handler runs. That can stop an injected request for an operation outside the task’s grants. An allowed operation chosen for the wrong reason can still pass.

Watch gives its analysis model no shell, browser or notification tools. It checks the structure and cited evidence of the response, and the model cannot change recipients or authoritative package ranges. There is still judgment inside news filtering: accepted classifications can suppress some noncritical news. We examine that limit in the [Security Watch article](https://shielda.ai/blog/security-watch-when-no-alert-arrives/). [Watch trust model](https://github.com/ShieldaAI/security-watch/blob/abde870beb5058d8e82a071df11afb0ba29aecda/SECURITY.md#trust-model)

Guard’s executor also controls access to memory entries. Reads and writes require grants, and each write creates a version. When the host quarantines an entry, the recorded read history allows that restriction to extend to entries derived from it. Rolling an entry back creates another version and keeps its sensitivity restrictions. These records help contain and investigate poisoned memory. They do not establish that a stored instruction is safe. Arbitrary summaries or files read outside those operations can lose that recorded history. [Governed memory integration](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/packages/executor/README.md#existing-execution-integrations)

Sensitive data needs its own restriction. Once trusted host code marks a task family as sensitive, Guard blocks external sends from that family, including otherwise approved sends. The host must still correctly identify the recipient and the resource being accessed. Copying the information to a new task requires the host to preserve the context; a new summary does not make the information public. [Sensitive-context rules](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/docs/threat-model.md#how-the-alpha-limits-those-actions)

## A tool or execution environment exposing more than expected

Managed MCP connections bind operations to reviewed metadata and a connection session. List-change notifications quarantine registered operations. Refreshing the registry invalidates earlier approvals even when the descriptors look unchanged. This addresses changes after review. It cannot reveal malicious implementation behind an unchanged descriptor, or guarantee discovery of a change the server never reports. The remote service still needs authorization. [Managed MCP lifecycle](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/packages/mcp/README.md#registry-changes-and-failures)

For code execution, the executor includes a launcher that copies selected files into a nonroot Linux container with a read-only root filesystem, dropped capabilities and networking disabled. Separate restricted HTTP adapters enforce configured origins, address checks and response limits. These are integrations the host must choose and configure. They do not create a complete networked coding-agent environment, and data deliberately copied into the container remains available inside it. [Enforced container boundary](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/deployment/README.md#enforced-boundary)

We inspected these published integration contracts; the local examples in this article do not test container isolation or a hostile remote MCP server. Those need separate checks in the actual deployment. [Execution integrations and release gates](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/packages/executor/README.md#existing-execution-integrations)

## A failed response after a completed change

Before calling the handler, the durable executor records its decision to allow the action, consumes the approval and reserves the required budget. If the outcome is uncertain, it keeps that unresolved state across a restart. The operator has to reconcile it using evidence of what the backend did. This addresses the retry risk, but it does not deduplicate every new action with equivalent arguments. The backend still needs an idempotency key or a way to look up the earlier attempt.

Watch handles uncertain notification receipts similarly. An unknown delivery is held for review rather than automatically resent. Neither an error from a tool nor a missing email receipt establishes that nothing happened. The dedicated articles test both cases. [Guard recovery](https://shielda.ai/blog/agent-guard-permission-to-try-again/) · [Watch delivery](https://shielda.ai/blog/security-watch-when-no-alert-arrives/)

Stopping work has a related limit. Deadlines, budgets and revoked grants limit which operations the task can start next. Guard also forwards cancellation. Cancellation remains cooperative. It cannot forcibly stop arbitrary handler code or retract a change a remote service has already accepted. Independently queued work still needs its own enforcement. The embedded core also remains memory-only; durable recovery requires the separate executor.

## An account that looks authorized while its task is not

Agent Map exposes scoped task relationships, grants, bindings and known gaps. That helps us find a route worth investigating. Its snapshots exclude action and approval records. For a particular operation, we also need the task’s authority history, the execution record and evidence from the backend. [Agent Map operations](https://github.com/ShieldaAI/agent-guard/blob/e8d8e82b31d7e4c60d565d9d37721953cc33c048/packages/agent-map/README.md#shared-operations)

We tested that distinction with six hand-written cases ending in the same worker requesting the same production deployment of payments revision `r17`. Two were authorized, three exceeded their authority, and one had an incomplete record. One violation used approval for `r16`; another had a production grant narrowed to staging during a handoff.

One fresh Codex session saw only the final requests and marked all six unknown. Another received the same policy and requests with their available authority histories. It identified the two supported cases and three violations, and left the incomplete case unknown. Expected judgments were fixed beforehand, and each reviewer made one pass. This shows the information needed in this exercise, without measuring a detection rate for real agent traffic. [Six cases and recorded judgments](https://shielda.ai/blog/examples/security-watch-and-agent-guard/review-cases.json)

We would keep the incomplete case in later evaluations. Guessing whenever the record is missing would make the reviewer more decisive without making the investigation more reliable.

The inventory and delegation scripts linked above were added on 5 November as runnable reproductions against the exact public releases. They use synthetic data and local state. [Reproduction instructions](https://shielda.ai/blog/examples/security-watch-and-agent-guard/README.md)

For a first integration, we would choose a service whose owner can verify the inventory and one sensitive operation that can go through Guard. Give an investigation read permission, try the forbidden change through a specialist, then run the same operation with a separate authorized task. Keep the records needed to explain both outcomes. That gives the team a specific piece of coverage to check again when the workflow changes.

[Continue to part three: Security Watch when no alert arrives.](https://shielda.ai/blog/security-watch-when-no-alert-arrives/)
