Repository navigation
fix(typescript): honor timeoutSeconds in DockerSandboxProvider executeCode - #3119
Closed
jlaportebot (jlaportebot) wants to merge 48 commits into
Closed
jlaportebot (jlaportebot) wants to merge 48 commits into
jlaportebot (jlaportebot) wants to merge 48 commits into
Conversation
- Add CommandCheckResult dataclass to enforcer.py - Add check_command() method to RingEnforcer class - Integrate with existing DENIED_COMMANDS from hypervisor.sandbox - Extract base command from command strings with arguments - Add comprehensive unit tests in test_command_denylist.py - Export CommandCheckResult from rings package Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…icrosoft#3008) Previously _evaluate_flat and _evaluate_rules silently skipped backends whose BackendDecision carried a non-None error field. If every registered backend errored, evaluation fell through to the configurable default action (which can be allow), converting a backend crash into a permit decision. Fix: invert the condition so a non-None error immediately returns a deny PolicyDecision with audit_entry["error"]=True and error_detail captured for post-incident investigation. Later backends in the list are not consulted. Adds three regression tests in test_policy_backends.py covering: - error backend denies instead of falling through to default - subsequent backends not reached after an error - healthy backend after YAML miss still returns its own decision correctly Security audit: docs/security/audits/2026-06-12-evaluator-backend-error-fail-closed.md Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…gate (microsoft#3016) The vendored-patch-audit gate requires every lockfile change to ship a dated docs/dependency-audits/ doc. Dependabot never authors that doc, so every Dependabot PR failed this required check by construction, blocking routine patch/minor bumps. Resolve the bump type via dependabot/fetch-metadata (already used, same pinned SHA, by auto-merge-dependabot.yml) and exempt only non-major Dependabot updates — the same set that workflow already auto-merges. Human PRs and Dependabot major bumps still require the audit doc; a missing/empty update-type or a non-Dependabot actor falls through to enforcement (fail-closed). Closes microsoft#2975 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…design (microsoft#2866) * feat(supply-chain): add PR-time SBOM diff workflow Generates SPDX-JSON SBOMs for both base and head of every PR, computes the added/removed/version-bumped delta, and posts a markdown summary as an idempotent PR comment (hidden marker keeps repeat runs from stacking). Catches transitive dependency creep that lockfile diffs alone miss. - scripts/diff_sbom.py: pure-stdlib SPDX-JSON diff renderer; sanitises hostile package names against markdown/log injection; caps rendered added entries at 500 to prevent comment-flood DoS. - scripts/tests/test_diff_sbom.py: 37 unit tests (purl parsing, sanitisation, diff math, truncation cap, render, end-to-end). - .github/workflows/sbom-diff.yml: on: pull_request (not pull_request_target); workflow-level contents:read; pull-requests:write scoped to the comment job only; every action SHA-pinned; BASE_REF and HEAD_REF passed via env to avoid GHA expression shell-injection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> * refactor(supply-chain): split SBOM diff into pull_request + workflow_run pair Adopt the industry-standard two-workflow pattern for safely commenting on fork PRs. Eliminates the residual risk that attacker-controlled `scripts/diff_sbom.py` from a fork PR could influence the comment body. Changes: - sbom-diff.yml: drop the comment job. Job becomes generate-only; runs anchore against base + head checkouts and uploads SBOM JSON files as artifact `sbom-diff-inputs`. Workflow-level permissions reduced to `contents: read` (no job needs write anymore). - sbom-diff-comment.yml (new): `on: workflow_run` against sbom-diff.yml. Runs in trusted base-repo context. Sparse-checks-out only `scripts/diff_sbom.py` from the default branch. Downloads the artifact from the triggering run via run-id. Re-derives PR identity from the workflow_run head SHA via the GitHub API (`listPullRequestsAssociatedWithCommit`) -- never trusts artifact contents for routing. Renders markdown via the trusted script. Posts or updates the comment with the `<!-- sbom-diff-bot -->` marker. Security properties preserved or improved: - Fork PRs now get a comment (previously fork PRs failed with 403 because pull_request downgrades the token; workflow_run runs in base context with a full token). - Attacker control of the comment body is eliminated: the rendering script and the PR-identity lookup both live in the trusted half. - PR-routing tampering is impossible: artifact contains data only; PR number/refs come from the GitHub API keyed on workflow_run.head_sha. - Bootstrap (this PR) gracefully no-ops the comment step when the diff script is not yet on the default branch, surfacing a warning so reviewers know to inspect the artifact directly. Sign-off: Jack Batzner <jackbatzner@microsoft.com> Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> * fix(supply-chain): harden SBOM diff against PR-misrouting, DoS, and mention spam Address blocking and non-blocking findings from the red-team review of the two-workflow SBOM diff design: PR-misrouting (blocking) - sbom-diff-comment.yml: prefer the authoritative workflow_run.pull_requests array (populated for same-repo PRs); fall back to listPullRequestsAssociatedWithCommit only for fork PRs. - Re-fetch the candidate PR and require pr.head.sha === workflow_run.head_sha before posting. Skip with a warning otherwise. This closes the stale- comment race where commit A's slow trusted run could overwrite the comment for the newer commit B. - Add a concurrency group keyed on workflow_run.head_sha with cancel-in-progress: true so a newer push pre-empts in-flight stale runs. DoS via unbounded sections (blocking) - diff_sbom.py: cap added/removed/bumped each at 500 (was: added only). - Add DEFAULT_MAX_SBOM_BYTES (64 MiB) and reject oversized SBOMs at load time via path.stat() before invoking json.load, so a hostile lockfile cannot balloon process memory before truncation. - render_markdown emits parallel truncation notices for all three sections. - New CLI flags: --max-removed, --max-bumped, --max-sbom-bytes. Mention / notification spam (non-blocking) - _sanitize_cell now neutralises GitHub auto-link triggers: '#' -> 'µsoft#35;' then '@' -> 'µsoft#64;' (order matters - reversing it clobbers the entity). Hostile package names embedding @user, @org/team, or microsoft#1234 can no longer ping people or autolink in the bot comment. Tests - +5 new tests: mention neutralisation, removed/bumped truncation caps, parallel render notices, and oversized SBOM rejection (42 total). - 211/211 scripts/tests/ pass, ruff clean. Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> * chore: fix CI failures on PR microsoft#2866 Three CI failures fixed: 1. policy-engine-ci.yml drift (Check generated workflows + inline-script-tests): regenerated via scripts/ci/generate_workflows.py --write. Drift was pre-existing on main; surfaces on every PR until regenerated. 2. spell-check: replace UK spellings with US (sanitises -> sanitizes, neutralise -> neutralize) in scripts/diff_sbom.py and the workflow. 3. spell-check: add legitimate proper nouns and jargon to repo dictionary (.cspell-repo-terms.txt): anchore (vendor), octocat (GitHub example), sboms (acronym plural), Syft/syft (Anchore tool). Local validation: - pytest scripts/tests/test_diff_sbom.py: 42 passed - pytest tests/ci/test_generate_workflows.py: 13 passed - ruff check: All checks passed! Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(scripts): cover multi-version overlap + clarify SBOM diff comments Address review feedback on PR microsoft#2866: - Add unit test exercising multi-version package overlap (e.g., lodash@4.17.20 + 4.17.21 in base, 4.17.21 + 4.17.22 in head). Documents that diff_sboms keys by (ecosystem, name) and emits a single bumped entry (oldest -> newest), matching the design choice favoring readable PR comments over per-version fan-out. - Expand inline comment on _extract_packages to explain why SPDX synthetic root packages (SPDXRef-DOCUMENT, name='') are skipped. - Add block comment on actions/checkout pin documenting that df4cb1c0 (v6.0.3) matches the convention used by 83 workflows on main. Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> --------- Signed-off-by: Jack Batzner <jackbatzner@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…#3022) The *.md override shadowed the default * line, meaning @imran-siddique approvals did not satisfy the CODEOWNER requirement for PRs touching markdown files. This left PRs approved by the maintainer stuck on REVIEW_REQUIRED despite the intent of the default ownership rule. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…icrosoft#3011) (microsoft#3013) * docs: add Engine API contract spec and OpenAPI 3.1 document (Epic 0, issue microsoft#3011) Create docs/studio/engine-api-contract.md and docs/studio/openapi.yaml to define the AGT Studio Engine API before implementation begins, fulfilling the gate requirement in ADR 0028 lines 142-148. - engine-api-contract.md: human-readable spec covering all 12 HTTP endpoints, three capability flags (runtime_mutating, user_intent_required, read_only_surface), read-only invariant with client-allowlist worked example, auth model (loopback/non-loopback), error envelope, pagination model, conformance rules, excluded endpoints (POST /api/v1/policy/reload), and WebSocket route reservation (/api/v1/events, Epic 7a) - openapi.yaml: OpenAPI 3.1 document with x-capability-flags extension on every operation, full request/response schemas, reusable error and pagination components, and BearerToken security scheme; passes npx @redocly/cli lint with zero warnings - mkdocs.yml: add Studio nav section linking to engine-api-contract.md No existing source files modified. Docs link check and frontmatter check pass. Closes microsoft#3011 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * docs: address peer review on Engine API contract Ground trust_level enum in the real trust_level_for_score vocabulary (untrusted, probationary, standard, trusted, verified_partner) instead of invented values, document the reserved WS /api/v1/events route with its three capability flags in both files (spec flag table + section 12, and an x-reserved-routes block in openapi.yaml), exclude reserved routes from the client allowlist, add the optional resolution_metadata field to FixtureResult to match policy_test.FixtureResult, and clarify how inline fixtures are adapted for policy_test.replay. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * docs: fix spell check failures in engine API contract Replace informal 'footgun' with 'dangerous pattern', fix two example error messages that contained the intentional typo 'actiom' (the spell checker flags example strings too), and add Redocly to the repo cspell terms file as it is a recognised tool name. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> --------- Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ization in base.py (microsoft#2994) * fix: document verify_intent lifecycle narrowing and finish UTC normalization in base.py - Add CHANGELOG entry under [Unreleased] > Changed documenting that verify_intent now requires EXECUTING state only (previously APPROVED was also accepted). The lifecycle is strictly declare -> approve -> execute -> verify. Closes microsoft#2908. - Expand the guard comment in intent.py to explain why APPROVED is rejected: without an execution phase there are no records to compare against the declared plan. - Replace all 5 naive datetime.now() calls in integrations/base.py with datetime.now(timezone.utc) for consistency with UTC normalization done in the adapters (PR microsoft#2572): - ExecutionContext.start_time default factory - event_base timestamp in _run_policy_checks - elapsed-time / timeout comparison - DRIFT_DETECTED event timestamp - CHECKPOINT_CREATED event timestamp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix: add fastembed to REGISTERED_PACKAGES in dep-confusion scan fastembed is a real PyPI package (fast embedding generation from Qdrant) referenced in agent-os/pyproject.toml line 61. The dep-confusion scanner was flagging it as unregistered because it was missing from REGISTERED_PACKAGES. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix: add fastembed to cspell word list and clean up comment - Add 'fastembed' and 'FastEmbed' to .cspell.json words list so the spell checker does not flag the package name string and comment - Remove brand name from dep-confusion comment to avoid future spell-check churn on proper nouns Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix: update tests to use timezone-aware datetimes for start_time The UTC normalization of ExecutionContext.start_time (datetime.now() -> datetime.now(timezone.utc)) broke tests that explicitly set start_time to a naive datetime. Update all four affected test files to use datetime.now(timezone.utc) so the subtraction in _run_policy_checks does not raise TypeError. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix: defensive UTC normalization for naive start_time and drop out-of-scope changes Address review feedback from @imran-siddique: 1. Add defensive normalization at base.py timeout check: if ctx.start_time is naive (set by external callers before the default factory was made tz-aware), convert it to UTC via astimezone() before subtracting. astimezone() correctly interprets the naive value as local time and converts it to UTC; replace(tzinfo=...) would not adjust the value. This protects external callers that still pass naive datetimes without breaking the UTC-aware fast path. 2. Add test_blocked_when_timeout_exceeded_naive_start_time to explicitly cover the defensive normalization path with a naive start_time. 3. Revert .cspell.json and scripts/check_dependency_confusion.py to main (fastembed additions are already on main and out of scope for microsoft#2908). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix: add datetimes to cspell wordlist The word 'datetimes' appears in the defensive normalization comment added in base.py and is not in the default cspell dictionary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> --------- Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
* feat(examples): add Google ADK governed examples Signed-off-by: joshua <allenselvaraj12@gmail.com> * fix(examples): address review feedback Signed-off-by: joshua <allenselvaraj12@gmail.com> * fix(docs): address spell check feedback Signed-off-by: joshua <allenselvaraj12@gmail.com> --------- Signed-off-by: joshua <allenselvaraj12@gmail.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…dget rules (microsoft#2766) * feat(agent-os): add dynamic policy conditions v1 Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> * test(agent-os): set ALLOW default in v1 dynamic policy tests Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> * docs(specs): align DYNAMIC-POLICY-CONDITIONS v1 audit semantics with implementation Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> --------- Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…r handling (microsoft#2801) * fix(ci): scope permissions per-job, harden summary step error handling - Move top-level pull-requests/issues/write permissions to per-job scope (ai-agents and summary) per Scorecard TokenPermissionsID rule - Add continue-on-error: true to summary step so comment-post failures never fail the whole workflow - Wrap comment create/update in try/catch that warns on any error - Always write job summary via core.summary regardless of comment status - Introduce RUN_MARKER so summary aggregates only current-run comments - Replace regex-based parseVerdict with marker-based parseAgentStatus - Inline overallVerdict using rows.some() to remove intermediate variable - Upgrade fallback-model from gpt-4o-mini to gpt-4o for consistency * fix(ci): remove duplicate pull-requests permission and dead overallVerdict block Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> --------- Signed-off-by: Dhinesh Ponnarasan <dhineshponnarasan@gmail.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…l OpenCode plugin contract (microsoft#2993) * Fix open code plugin. Adapt to real open code plugin contract, original code was never called. Signed-off-by: Alexander Wiedemann <wiedemann@bluehands.de> * Remove opencode-ai/plugin dependency because it was explicitly mentioned in the original PR Signed-off-by: Alexander Wiedemann <wiedemann@bluehands.de> * - revert temporary changes to package.json * comment about throwing in event handler Signed-off-by: Alexander Wiedemann <wiedemann@bluehands.de> --------- Signed-off-by: Alexander Wiedemann <wiedemann@bluehands.de> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.25.12 to 0.28.1. - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2025.md) - [Commits](evanw/esbuild@v0.25.12...v0.28.1) --- updated-dependencies: - dependency-name: esbuild dependency-version: 0.28.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…soft#3002) Bumps [pyo3](https://github.com/pyo3/pyo3) from 0.28.3 to 0.29.0. - [Release notes](https://github.com/pyo3/pyo3/releases) - [Changelog](https://github.com/PyO3/pyo3/blob/main/CHANGELOG.md) - [Commits](PyO3/pyo3@v0.28.3...v0.29.0) --- updated-dependencies: - dependency-name: pyo3 dependency-version: 0.29.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…icrosoft#3023) Two locations stored the raw context reference instead of a defensive copy, causing test_flat_yaml_match_isolated_from_top_level_mutation to fail with `assert X is not X` (same object identity). The PR microsoft#2766 dynamic-conditions merge introduced the shared.py path; the evaluator.py path (fail-closed except block) was a pre-existing latent bug. Fixes the agent-os 3.11/3.12/3.13 CI failures on main. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
… (microsoft#3025) Adds examples/acs-atr-annotator/: a custom ACS policy backed by a host annotator dispatcher that runs the open-source Agent Threat Rules engine (pyatr) over the policy target and denies on a match. - ATRAnnotator.dispatch runs ATR and returns a free-form annotation; the thin ATRPolicy.evaluate translates it into an ACS verdict (deny on match, else allow). Verdicts use only decision/reason/evidence -- no effects[] (AGT D1). Evidence carries rule IDs + verification links. - pyatr is an optional, pre-1.0 dependency: lazy import with a clear ImportError; tests use pytest.importorskip. - Validated against the ACS runtime: demo.py and test_atr_annotator.py run through agent_control_specification (from PyPI) and assert deny on injection / allow on benign at both the input and pre_tool_call intervention points. Addresses microsoft#3018. Signed-off-by: Adam Lin <adam@agentthreatrule.org> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…0030) (microsoft#3015) Implements step 1 of the ADR-0030 migration: the versioned protocol models, RFC 8785 JCS digest helper, durable approval-store contract, and the approval coordinator. Purely additive — nothing is wired into the policy evaluator or the legacy approval handlers yet. The coordinator binds each approval to one action digest, records hash-linked, append-only approval-chain entries, resolves require_approval to a terminal allow/deny/expired, and performs fail-closed execution-time revalidation: action digest, policy version, chain version, expiry, chain integrity, and one-time consumption. LLM advisory votes are recorded but never satisfy a stage (ADR-0030 section 8). Refs microsoft#2478 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…rosoft#3027) * feat(engine-api): add capability-metadata library for AGT Studio Implements the capability-flag substrate from the Engine API contract (docs/studio/engine-api-contract.md sections 5 and 6): a CapabilityFlags model enforcing the read-only invariant at construction, a capability_flags decorator, an OpenAPI x-capability-flags injection hook, and the read-only client allowlist derivation. Library-only and purely additive; no routes. Closes microsoft#3026 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> * fix(engine-api): address review and spell-check - derive_studio_client_allowlist: guard against non-bool flag values and drop the prohibited is False comparison (AGENTS.md CodeQL guidance) in favour of isinstance + truthy check. - Replace is True/is False boolean-identity assertions in the capability tests with truthy/falsy asserts to match the project standard. - Add dunder to the cspell dictionary so the spell-check gate passes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> --------- Signed-off-by: Ricky Gummadi <ricky.gummadi@outlook.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
… evaluator (microsoft#3028) PromptDefenseEvaluator audited system prompts against 12 OWASP LLM Top 10 vectors but nothing on the agentic layer, even though AGT positions itself against the OWASP Agentic Top 10. This extends the evaluator with 5 agent-era vectors so a pre-deployment prompt audit also covers agentic risks: - cross-agent-auth (ASI-07) inter-agent authority boundary - transaction-guardrails (ASI-02) value-moving action guardrails - skill-provenance (ASI-04) signed/trusted skill loading - least-agency (ASI-01) least-privilege + goal-drift abort - encoding-injection (ASI-01) decoded payload treated as data, not command Each rule follows the module's existing discipline: bounded quantifiers (ReDoS-safe), min_matches=2 so attack vocabulary alone never scores as defended (the capability AND its constraint must both be present), plus a severity_map entry. VECTOR_COUNT stays dynamic (len(_RULES)). Adds positive + negative-control tests for all 5, regression tests for three false-positive classes (auth token vs. spending guardrail; data-pipeline "as input" vs. treat-as-untrusted; QA "verified" vs. provenance refusal), extends the STRONG_PROMPT fixture, and a docs/ vector->OWASP mapping table. red-team scan CLI docstring updated 12 -> 17. Regex vocabulary distilled from the open-source UltraProbe scanner (npm: ultraprobe, MIT). Signed-off-by: ppcvote <risky9763@gmail.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…crosoft#3029) Add a fifth OS native sandbox backend for Linux and macOS using the nono-py capability sandbox (Landlock / Seatbelt). The provider implements the existing SandboxProvider session contract: policy-driven config, host-side PolicyEvaluator gating, AST pre-scan, filtering network proxy for allowlisted egress, and one-shot sandboxed_exec per invocation with persistent session output/. - Add nono_sandbox_provider package (config, provider, lazy exports) - Add optional [nono] extra (nono-py>=0.10.1) and README provider docs - Add design proposal and runnable quickstart example with policy YAML - Add hermetic unit tests and opt-in integration tests (AGT_NONO_INTEGRATION=1) Signed-off-by: Aleksy Siek <aleksy@alwaysfurther.ai> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.14 to 8.0.16. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.16 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to 4.0.6. - [Release notes](https://github.com/form-data/form-data/releases) - [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md) - [Commits](form-data/form-data@v4.0.5...v4.0.6) --- updated-dependencies: - dependency-name: form-data dependency-version: 4.0.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…icrosoft#3030) Bumps [ws](https://github.com/websockets/ws) from 8.20.1 to 8.21.0. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](websockets/ws@8.20.1...8.21.0) --- updated-dependencies: - dependency-name: ws dependency-version: 8.21.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ernance-python/agent-os/extensions/copilot (microsoft#2962) * chore(deps-dev): bump @types/node Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.2 to 25.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * docs: add dependency audit for @types/node 25.9.3 (copilot) Satisfies the Dependency Audit Trail gate for the package-lock.json change. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ernance-typescript (microsoft#2960) * chore(deps-dev): bump @types/node in /agent-governance-typescript Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.2 to 25.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * docs: add dependency audit for @types/node 25.9.3 (typescript) Satisfies the Dependency Audit Trail gate for the package-lock.json change. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ernance-python/agent-os/extensions/mcp-server (microsoft#2959) * chore(deps-dev): bump @types/node Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.2 to 25.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * docs: add dependency audit for @types/node 25.9.3 (mcp-server) Satisfies the Dependency Audit Trail gate for the package-lock.json change. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
… in /agent-governance-python/agent-os/extensions/mcp-server (microsoft#2889) * chore(deps-dev): bump @typescript-eslint/parser Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.60.1 to 8.61.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.61.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * docs: add dependency audit for @typescript-eslint/parser 8.61.0 (mcp-server) Satisfies the Dependency Audit Trail gate for the package-lock.json change. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Imran Siddique <45405841+imran-siddique@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…soft#3033) * fix(ci): add tzdata, pyatr, nono-py to dep-confusion allowlist All three are registered PyPI packages flagged after recent merges: - tzdata: IANA tz database (Windows tz support in agent-os) - pyatr: AGT audit trail record library (acs-atr-annotator example, PR microsoft#3025) - nono-py: OS-native sandbox bindings (agt-sandbox[nono], PR microsoft#3029) Signed-off-by: Imran Siddique <imran.siddique@opaque.co> * fix(ci): add tzdata and pyatr to cspell allowlist Signed-off-by: Imran Siddique <imran.siddique@opaque.co> --------- Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.60.1 to 8.61.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.61.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.60.1 to 8.61.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.61.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…him (microsoft#2662 option 2) (microsoft#3019) * feat(agent-sandbox): log denied-command attempts via hardened-image shim The minimal-PATH hardened image (option 1 of microsoft#2662) prevents denied network/infra CLIs but blocks them silently ('command not found' / EACCES). The issue is explicit that for compliance, detecting the attempt matters as much as preventing it. Add docker/agt-deny-shim.py — a stdlib-only Python logging shim — and route the denied CLIs (curl, az, kubectl, terraform, …) to it in Dockerfile.sandbox, both at each binary's real path (absolute-path calls) and under its name in the pinned PATH dir (by-name calls). Each attempt writes a structured command_denied JSON record to stderr (captured in SandboxResult.stderr), optionally appends to $AGT_DENIED_LOG, and exits 126 so the real command never runs. The shim is Python because the image strips the execute bit off every shell; shells/interpreters/encoders stay disabled-but-unlogged. Docker-free tests cover the shim behavior and assert the Dockerfile wiring. This is option 2 of tracker microsoft#2662. Refs microsoft#2662 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(agent-sandbox): address review on deny-shim (microsoft#3019) Blocker 1: rename the record field ts -> timestamp to match the AGT audit-record convention. Blocker 3: open AGT_DENIED_LOG with os.open(O_NOFOLLOW) so a planted symlink cannot redirect the append. Required fixes: add 'set -f' to the Dockerfile loop (glob injection); skip routing when the name is already an allowed sandbox-bin entry (allow-list precedence); use an absolute python shebang instead of /usr/bin/env; merge the two stderr writes into one (atomicity); surface AGT_DENIED_LOG write failures on stderr instead of swallowing them. Blocker 2 (behavior change EACCES -> exit 126): documented in the shim, README, and the DENY_EXIT_CODE comment. Verified no in-tree caller gates on PermissionError, so no callers need updating. Nit 1: README documents that DENIED_LOGGED_BIN_NAMES replaces (not extends) the set. Nit 2: added a direct test for main([]). Refs microsoft#2662 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…Python + Rust) (microsoft#3014) * feat(agent-os): optional evidence-only detection backend for prompt injection Add a pluggable, default-off evidence backend to the prompt-injection detector, following the pluggable-backend pattern of ADR-0015. When a backend is registered via evidence_backends, its advisory EvidenceSignal is appended to DetectionResult.evidence after the deterministic verdict is computed. Evidence never influences is_injection/threat_level/injection_type/confidence/ matched_patterns and never blocks on its own. EmbeddingSignalBackend adapts the existing prompt_injection_embedding kNN signal to this interface, connecting it to the detection pipeline (see microsoft#2918); content normalization (microsoft#2957) remains upstream of any backend. With no backend registered the detector output is unchanged. A backend that raises is recorded as a static error code and never breaks detection; evidence carries no raw input text. Tests: verdict-parity (backend on vs off), evidence-never-blocks, backend-failure isolation, no-raw-text, and adapter default-off / fake-embedder cases. * feat(agentmesh): optional evidence-only detection backend for prompt injection Mirror the agent-os wiring in the Rust SDK, following ADR-0015's pluggable-backend pattern. PromptInjectionDetector gains an optional, default-off with_evidence_backends(...); each backend's advisory EvidenceSignal is appended to DetectionResult.evidence after the deterministic verdict is computed. Evidence never influences is_injection/threat_level/injection_type/confidence/ matched_patterns and never blocks on its own. DetectionResult is marked #[non_exhaustive] so the additive `evidence` field is non-breaking; EmbeddingSignalBackend adapts the existing prompt_injection_embedding kNN signal to the backend trait (see microsoft#2918). With no backend registered the detector output is unchanged. Tests: 6 new integration cases (verdict parity backend on vs off, evidence-never-blocks, adapter default-off / fake-embedder). agentmesh prompt_injection: 50 integration + 17 lib unit tests pass. * docs(adr): optional embedding evidence backend (ADR 0031) + crate re-export Document the optional, default-off evidence-backend design (pluggable ADR-0015 pattern, evidence-only, normalization upstream) and re-export EvidenceSignal / DetectionEvidenceBackend / EmbeddingSignalBackend from the agentmesh crate root for parity with the other prompt-injection types. Refs microsoft#2918 microsoft#2957. * fix(prompt-injection): address PR microsoft#3014 review — harden evidence backend Resolve the three confirmed bugs and five plausible issues from review. Confirmed bugs: - Rust: wrap backend.evaluate() in catch_unwind so a panicking backend (e.g. the embedding signal's cosine() asserting on a dimension mismatch) is recorded as a static backend_error instead of unwinding through detect() and bypassing the Err-only fail-closed path. Symmetric with Python's except-guard. - Rust: detect_without_audit now also runs collect_evidence, so the audit-free path is consistent with detect() (only the audit write is skipped). - REST API: DetectionResponse gains an evidence field and _detection_result_to_response maps it, so configured backends actually surface through /api/v1/detect/injection. Plausible issues: - EvidenceSignal rejects non-finite (NaN/inf) scores: Python raises in __post_init__; Rust drops to a non_finite_score error code. - Evidence-only invariant is enforced, not conventional: blocks=true is rejected (Python) / forced false (Rust) at the boundary. - Audit oracle: raw evidence scores are stripped from the durable audit copy so the margin cannot be used as a per-request evasion oracle; the live DetectionResult keeps raw scores for telemetry. - Python EmbeddingSignalBackend annotates signal: EmbeddingSignal (via TYPE_CHECKING) instead of object, dropping the type: ignore. - Rust EmbeddingSignalBackend moves the Send + Sync bound onto the struct so a non-Send/Sync embedder fails at construction, not at the coercion site. Tests: +7 Python (prompt_injection), +2 Python (server REST evidence), +3 Rust integration (panic guard, blocks/NaN coercion, audit score strip), +1 Rust unit (detect_without_audit evidence). Full Python prompt_injection + server suites and cargo test --release --workspace all green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…3037) The flat evaluator's rule-match branch set context_snapshot to the live context reference instead of a copy, leaving audit records sharing state with the caller. Every other branch already used copy.deepcopy; this one was missed in microsoft#3023. Fixes TestContextSnapshotIsolation::test_flat_yaml_match_isolated_from_top_level_mutation. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…microsoft#3038) request_trust, initiate_handshake, and check_policy were changed to raise NotImplementedError (honest stubs) rather than return synthetic success responses that bypassed real gRPC calls. The tests still asserted the old fabricated return values, causing them to fail on all Python versions. Update each test to assert the expected NotImplementedError with a 'round-trip' message match. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…ve matching and injection prevention - Make check_command() case-insensitive to prevent bypass via case variation - Strip trailing shell metacharacters (;, &, |) to prevent command injection - Add comprehensive tests for edge cases (whitespace, special chars, partial matches, large inputs) - Update CHANGELOG.md and README.md with v2.1 additions - All 805 tests pass Signed-off-by: jlaportebot <jlaportebot@gmail.com>
AGT satisfies AARM Extended (all R1-R9, verified Jun 14 2026) and maps to all five ATF elements. Adds badges, Standards Compliance table rows, and Documentation compliance links for both. Adds AARM and ATF to the cspell word list. Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…icrosoft#2864) Signed-off-by: jlaportebot <jlaportebot@gmail.com>
- Apply ruff --fix to resolve UP045, UP035 type annotation issues - Apply ruff format to standardize code style across 30 source files - All 480 unit tests continue to pass Signed-off-by: jlaportebot <jlaportebot@gmail.com>
- Replace timezone.utc with datetime.UTC (Python 3.11+) - Fix import sorting (I001) - Apply line wrapping and formatting fixes - No functional changes Signed-off-by: jlaportebot <jlaportebot@gmail.com>
- Add docstring to ConfigScanner.scan() method in agent_discovery/scanners/config.py - Update CHANGELOG.md [Unreleased] section with command denylist enforcement feature - Update README.md to mention command denylist enforcement in Agent Hypervisor and runtime package descriptions Addresses AI review comments about missing docstrings and documentation sync. Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Signed-off-by: jlaportebot <jlaportebot@gmail.com>
- Add execute permission - Remove 'import hashlib' pattern (SHA-256 used for non-cryptographic purposes) - Add 'hmac\.' pattern to catch hmac usage beyond import statements - Add comment explaining why hashlib is excluded
…eCode - Store session config (including timeoutSeconds) in createSession - Use stored timeout in executeCode via 'timeout' command inside container - Add timeout detection (exit code 124) and proper killReason - Clean up sessionConfigs map in destroySession - Add regression test for custom timeout behavior Fixes microsoft#3118
jlaportebot (jlaportebot)
requested review from
MohammadHaroonAbuomar and
Imran Siddique (imran-siddique)
as code owners
June 20, 2026 01:01
|
🔴 Contributor Check: HIGH
Automated check by AGT Contributor Check. |
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
Contributor
Author
|
Superseded by #3120 with clean branch from upstream/main |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #3118 - The TypeScript
DockerSandboxProviderwas ignoring thetimeoutSecondsconfig parameter when executing code.Changes
timeoutSeconds) increateSession()executeCode()viatimeoutcommand inside containerkillReasonsessionConfigsmap indestroySession()Testing
All sandbox tests pass:
creates, executes, and destroys a sessionuses custom timeoutSeconds from session config(new test)The fix uses the
timeoutcommand inside the container (available inpython:3.11-slim) to properly enforce execution time limits. The Node.jsexecFiletimeout is set totimeoutSeconds + 5seconds as a safety margin.