Skip to content

feat(agent-vault): session logs - #407

Open
saifsmailbox98 wants to merge 42 commits into
mainfrom
agent-vault-activity-logs
Open

saifsmailbox98 wants to merge 42 commits into
mainfrom
agent-vault-activity-logs

Conversation

@saifsmailbox98

@saifsmailbox98 saifsmailbox98 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Description 📣

Adds the proxy side of Agent Vault session logs. The proxy records each request an agent makes through a session that has session logs on, encrypts the records with the session's key, and uploads them to the customer's S3 bucket every 60 seconds or every 1,000 records. Records are held in memory within fixed limits, and nothing is written to disk. Backend PR: Infisical/infisical#8275

Changes to existing behaviour:

  • Resolve: The proxy sends hasSessionLogKey and reads a new sessionLogs field. With an older backend the field is missing, so the proxy doesn't record anything.
  • 404s from resolve: A 404 ends the session only when Infisical names it NotFound. A 404 from a load balancer or a missing route is treated like an outage, so cached credentials keep working through the grace period.
  • Targets: A port must be a number from 1 to 65535, or the proxy refuses the request with a 400 before it resolves the session. An opaque request target is now refused after the session lookup instead of before, so it's logged and recorded as blocked.
  • Logs: A very long HTTP method is cut to 32 characters in log lines, the same way long paths are.
  • Shutdown: After the HTTP server stops, the proxy spends up to 5 more seconds uploading what it still holds, so a shutdown can take about 15 seconds.

Type ✨

  • Bug fix
  • New feature
  • Improvement
  • Breaking change
  • Documentation

Tests 🛠️

Run this proxy build and follow the steps to verify in Infisical/infisical#8275.


@infisical-review-police

Copy link
Copy Markdown

💬 Discussion in Slack: #pr-review-cli-407-feat-agent-vault-ship-session-activity-from-the-proxy

Posted by Review Police — reviews, comments, new commits, and CI failures will stream into this channel.

@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5 Tier: plus

[High risk] Adds session logging infrastructure to the proxy.

The PR appears safe to merge based on the current review.

Summary

The PR adds in-memory Agent Vault session-log recording, encryption, and periodic S3 uploads. It also updates session resolution, request-target validation, refusal auditing, and shutdown flushing.

  • The change since the previous review only revises a disablement warning message.

Reviews (24) · Last reviewed commit: "fix(agent-vault): say session logs are d..."

Comment thread packages/agentvault/activity.go Outdated
Comment thread packages/agentvault/proxy.go Outdated
Comment thread packages/agentvault/activity_ship.go Outdated
Comment thread packages/agentvault/activity.go Outdated
Comment thread packages/agentvault/activity_ship.go Outdated
@veria-ai

veria-ai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 3 · PR risk: 0/10

Every request that reaches forwardHTTP becomes a record, a blocked one included,
since under the default any-host policy an agent reaching somewhere nobody
configured is ordinary passthrough traffic and logging only brokered calls would
make the one request worth catching invisible.

Records go into a bounded per-session ring; a flusher drains it every 60 seconds
or every 1000 records, seals each slice with AES-256-GCM, POSTs the metadata for
a presigned URL and PUTs the ciphertext to the customer's bucket. The hot path
costs one append under a mutex.

Chunk ids are ULIDs rather than a counter: a counter resets whenever the session
cache evicts an entry, which happens at nine ordinary sites, and would then
collide with the server's unique index for the rest of the session's life.

Resolve carries the key exactly once per session. The proxy reports that it
holds one and the backend skips the unwrap, which is a KMS round trip, on every
poll after the first.

Nothing is persisted to disk. A failed upload is retried with the same chunk id,
which the server replays idempotently; an outage pauses rather than discards; and
a per-tick breaker keeps a hundred spools against a dead bucket or an unreachable
control plane from costing a hundred serial timeouts.
@saifsmailbox98
saifsmailbox98 force-pushed the agent-vault-activity-logs branch from 87aebb9 to 5f92a4e Compare September 24, 2026 00:55
Comment thread packages/agentvault/activity.go Outdated
Comment thread packages/agentvault/activity_ship.go Outdated
@saifsmailbox98 saifsmailbox98 changed the title feat(agent-vault): ship session activity from the proxy feat(agent-vault): ship session logs from the proxy Sep 26, 2026
Comment thread packages/agentvault/session_log.go Outdated
saifsmailbox98 and others added 6 commits September 26, 2026 10:37
…f ULID

uuid.NewV7 is monotonic within the process, so chunks split from one flush keep their seal order, and a minting
failure now drops the batch with an error instead of panicking. oklog/ulid goes back to an indirect dependency.
The pinned crypto vector is regenerated for the new fixture id.
… log key

Every way a chunk leaves the proxy returns its bytes to the pending cap, and resolve asks for the key until the
proxy holds it.
…tdown shipping once, and what a sealed chunk holds

The old shutdown race test only caught its bug by luck; the new one blocks the run loop's upload so a second post
fails deterministically. The wiring test now decrypts the uploaded chunk and checks its records.
…er test that shares it

The backend's copy of the vector tested no backend code and was removed, so these point at the browser instead.
Comment thread packages/agentvault/session_log_ship.go Outdated
Comment thread packages/agentvault/session_log.go Outdated
Comment thread packages/agentvault/session_log.go Outdated
Comment thread packages/agentvault/session_log_ship.go Outdated
@saifsmailbox98 saifsmailbox98 changed the title feat(agent-vault): ship session logs from the proxy feat(agent-vault): session logs Sep 28, 2026
@saifsmailbox98

Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread packages/agentvault/session_log.go Outdated

@scott-ray-wilson scott-ray-wilson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-reviewed at 37633ba. Verified live against the dev stack: uploads to an Object Lock bucket with the signed checksum, the new AAD and UUIDv7 ids decrypting in the browser, the gone-session drop on Infisical's NotFound, and the shutdown flush on a quiet proxy. go test -race is clean over 20 runs. One Medium below, plus a follow-up on the 404/401 thread.

Comment thread packages/agentvault/session_log.go Outdated
r.forgetIdleSpoolsLocked(started)
r.mu.Unlock()
}
for _, spool := range r.dueSpools(pass, started) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Medium: the final flush ships sessions one at a time, so a restart loses most sessions' last minute

Each due session costs a POST and then a PUT in series, so the 5s close budget covers roughly 5s divided by two round trips. A probe with 60 active sessions at 100ms per call lost 36 of them (720 records) on shutdown; at 50ms it lost 13. The only trace is the "session log records were not shipped before shutdown" warning, and a rolling deploy restarts every proxy this way.

This also bears on the earlier flushMu thread. The run loop doesn't check stop first, so when a wake or tick is ready at the same time, select can start a new pass on context.Background() after stop is closed (113 of 200 trials in a probe), and close() then waits for it. That reproduces the overrun (close took 11.5s against the 5s budget in one run, losing the last session's records) without SIGTERM landing during a slow upload.

Suggest sealing every ring first, then shipping with bounded parallelism (as refreshParallelism does for refreshes), checking stop with a non-blocking select at the top of the loop, and running passes on a context that stop cancels.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Stop is checked first now and passes run on a context stop cancels, so close() takes over at once. Sessions also ship 8 at a time now, network calls in parallel and state changes still in one goroutine, so the final flush gets through a lot more in 5s.

Comment thread packages/agentvault/session_log.go Outdated
log.Warn().Err(err).Msg("agent-vault: Infisical rejected this proxy's token, holding activity")
return false

case isSessionGone(err):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The 404 half works: I checked it live against the real backend, and a gone session now logs "Infisical no longer accepts session logs for this session, dropping what was held". Two things are left:

  • Any 401 that isn't ProxyTokenRejected still counts as a gone session in isSessionGone, so a 401 from a middlebox or an auth proxy in front of Infisical drops the session's buffer as if the session had ended. Infisical's own 401s carry a name (UnauthorizedError), so the same name check as the 404 would work.
  • The 403 case is concretely TokenError. An invalid or expired proxy JWT (say, after an AUTH_SECRET rotation) gets a 403 TokenError from the error handler, which classifyChunkError treats as a refused chunk and drops, logging an error each time, while resolve treats the same 403 as an outage. Classifying TokenError like ProxyTokenRejected would hold the data until the proxy logs in again.

…ions in parallel, and hold chunks on foreign 401s and TokenError
Comment thread packages/agentvault/session_log.go Outdated
Comment thread packages/agentvault/session_log.go Outdated
…lthy pass never evicts chunks it just sealed
Comment thread packages/agentvault/session_log.go
…requests arriving mid-upload wait for the next pass instead of shipping one per round
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants