Skip to content

fix(guardian): evaluate steps of one session in order - #381

Open
4ktLuffy wants to merge 2 commits into
GenAI-Security-Project:integrationfrom
4ktLuffy:fix/serialize-session-steps
Open

4ktLuffy wants to merge 2 commits into
GenAI-Security-Project:integrationfrom
4ktLuffy:fix/serialize-session-steps

Conversation

@4ktLuffy

Copy link
Copy Markdown

What changed

Steps in one session are now evaluated one at a time, so a step reads the IFC labels the previous step wrote and a concurrent step can no longer drop secret. The duplicate request_id check runs in the same queue as evaluateStep, so it still sees every earlier step. Steps in different sessions still run concurrently.

Which issue does this implement

Closes #310

  • This is an editorial correction (typo, grammar, link, formatting) with no change in
    meaning, so it needs no issue

Base branch

  • integration, because this touches the specification, schemas, a reference
    implementation, an adapter, tests, or CI
  • main, because every changed path is on the documentation lane allowlist in
    CONTRIBUTING.md

Type of change

  • Specification change (schema, hooks, events, AgBOM)
  • Reference implementation or adapter
  • Documentation
  • Tooling or CI
  • Governance (licensing, security policy, contributor docs)

I tested this

  • I synced my branch with the base branch before opening this
  • uv run pytest -v passes on my machine
  • uv run mkdocs build --strict passes on my machine

TypeScript only, so I ran the agt checks, on macOS with Bun 1.3.11:

Trade-off: a step that waits on AGT now holds later steps of the same session until it finishes or the OPA timeout fails it. Other sessions are not affected.

Note: #229 and #346 edit the same region of server.ts, so whichever lands second needs a small rebase.

Checklist

  • Commits are signed off with git commit -s (required by the DCO)
  • Prose follows STYLE.md
  • No secrets, tokens, or internal URLs in the diff

Security

  • This change has no security impact

It closes a path where a label marking secret data was lost between steps, so a later step was evaluated as if the session had never read secret data.

Two concurrent steps in a session each read the IFC labels before AGT was
awaited and replaced them after, so the later write could drop a label the
earlier step added, secret included. Queue steps per session, with the
duplicate request_id check in the same queue. Other sessions still run
concurrently.

Closes GenAI-Security-Project#310

Signed-off-by: Henos D <henosd19@gmail.com>
@github-actions

Copy link
Copy Markdown

Thanks for this. It is queued rather than ignored.

This pull request does not reference an issue carrying status:accepted, so a maintainer has not looked at it yet and will not until the underlying issue is triaged. Nothing here is rejected. See Current Priority Scope for what the project is working on, and help wanted for work that is already accepted.

If this is an editorial correction, tick that box in the description and this comment stops applying.

@drk-ram drk-ram left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested head 9136b7d9301cc3abbef561ecb0e988a88abd439b merged onto integration 1b8f970370011cbcbb491ffbcafff210d62f6fbd on Windows.

Bun 1.4.4 and 1.3.11 both pass bun run typecheck and 39 session-order, IFC-label, and session-context tests. Removing queue ordering fails the secret-label case; sharing one queue across sessions fails the independent-session case. Both mutations fail on both runtimes.

I found an uncovered branch: removing only the inSessionOrder wrapper around steps/toolCallResult still passes both new tests. A slow request followed by a fast result that adds secret then loses that label when the slow request finishes.

Please add a result-gate regression using the same bridge: start echo slow, send a same-session toolCallResult with output read-secret, await both, then send echo after. Assert the last snapshot retains secret. A result/result pair deserves the same check. My separate probes pass with this patch and fail with the result wrapper removed on both runtimes.

Queued duplicate detection and recovery after a failed evaluation also pass my probes. The complete Guardian run is not green: 1.4.4 has the same 13 baseline failures; 1.3.11 reaches the same 120-second timeout.

@President President left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - I reproduced the bug on integration (the last step saw only public), and with this PR it keeps secret. Looks good to me.

One thing to keep in mind - a step now waits in the queue with no deadline:

  • step 1's AGT call takes 6 s, step 2 waits behind it
  • the agent stops waiting after 5 s (the declared timeout_config) and falls into its fail-open posture

This is the README's "Bounded processing" gap, which #312 already tracks for this Guardian. So no need to fix it here - it is one more case for #312.

Removing the queue around steps/toolCallResult left both tests green. Add
a result behind a slow request and a result behind a slow result.

Signed-off-by: Henos D <henosd19@gmail.com>
@4ktLuffy

4ktLuffy commented Nov 3, 2026

Copy link
Copy Markdown
Author

Thanks, that branch was uncovered. Added the result-gate cases with the same bridge: a slow request then a toolCallResult with read-secret, and the same with a slow result first, each followed by echo after and asserting the last snapshot keeps secret.

Checked on macOS with Bun 1.3.11: with only the toolCallResult wrapper removed, both new tests fail in 3 of 3 runs; with the patch all 4 pass. bun test 1287 pass, 0 fail.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:needs-triage Not yet triaged. Applied by the issue forms

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

[Bug] Concurrent steps in one session overwrite each other's IFC labels, so a secret label is lost

3 participants