-
Notifications
You must be signed in to change notification settings - Fork 0
Trust Model
What Agents Shipgate does and does not do, by design. Verifiable from the source.
| Run agent code or import user modules | The OpenAI Agents SDK loader uses ast.parse only |
| Call tools | No HTTP client is ever instantiated for tool invocation |
| Invoke LLMs | The risk classifier is rule-based, not model-based |
| Connect to MCP servers | MCP loading is JSON-export only |
| Make network calls | All inputs are local files |
| Read files outside the manifest directory | Path traversal blocked; see Input safety |
| Collect telemetry | Not even anonymous usage stats |
These properties hold unless you opt into plugins.
As of v0.2, every path declared in shipgate.yaml (under tool_sources, openai_api, etc.) is resolved through inputs/common.py:resolve_input_path:
def resolve_input_path(base_dir: Path, value: str) -> Path:
base = base_dir.resolve()
raw_path = Path(value)
path = raw_path if raw_path.is_absolute() else base / raw_path
resolved = path.resolve()
try:
resolved.relative_to(base)
except ValueError as exc:
raise InputParseError(
f"Input path {value!r} resolves outside manifest directory: {resolved}"
) from exc
return resolvedA malicious manifest with path: ../../../../etc/passwd is rejected with InputParseError. This is a behavior change from v0.1 — sibling-directory specs that previously worked must now be moved into the manifest tree, symlinked in, or accessed via a separate manifest run.
Files are also size-bounded:
-
MAX_INPUT_FILE_BYTES = 10 MB(common.py) - OpenAPI
$refresolution:MAX_SCHEMA_RESOLVE_DEPTH = 32,MAX_SCHEMA_RESOLVE_NODES = 5000(truncated with anx-agents-shipgate-resolution-truncatedmarker rather than crashing)
YAML is parsed with yaml.safe_load only. The unsafe !!python/object/... constructor is rejected.
The openai_agents_sdk source type reads Python files via ast.parse and walks the tree for @function_tool decorations. It never imports the file. Practically:
- It detects direct decorator names (
@function_tool,@agents.function_tool,@openai_agents.function_tool). - It detects renamed imports (
from agents import function_tool as ft→ recognizes@ft). - It reads
name_overrideanddescription_overridefrom decorator kwargs. - It cannot detect dynamic wrappers, factory-built tools, runtime imports, or tools added to a list.
For production targets, this medium-confidence extraction triggers SHIP-INVENTORY-LOW-CONFIDENCE-PRODUCTION-SURFACE — your nudge to migrate the inventory to MCP or OpenAPI declarations. See Real-World Examples § OpenAI Agents SDK.
SHIP-DOC-SECRET-IN-DESCRIPTION matches patterns like sk-…, ghp_…, AKIA…, and password|secret|token|api_key: ${value}. The report records the pattern that matched (e.g. \\bsk-[A-Za-z0-9_-]{16,}), never the actual value. The SHIP-DOC-INJECTION-RISK finding similarly records the pattern, not the description text.
This is verified by tests/test_documentation_checks.py. If you see an actual secret leak into a report, that's a bug — please file a security advisory at SECURITY.md.
Third-party check plugins are the only opt-in escape from the static-by-default guarantee. Plugins are arbitrary Python code that gets imported and executed when:
AGENTS_SHIPGATE_ENABLE_PLUGINS=1 agents-shipgate scan ...The runtime overrides:
agents-shipgate scan --no-plugins # forces off, even if env is set
agents-shipgate list-checks --no-plugins # catalog without plugin entries
agents-shipgate explain --no-plugins SHIP-X # built-ins onlyWhen plugins ARE loaded:
- Only entry points from distributions other than
agents-shipgateitself are considered (registry.py:_is_builtin_entry_pointchecksdist.metadata["Name"]). - Each loaded plugin appears in the report:
"loaded_plugins": [ { "name": "compliance", "value": "acme_shipgate_checks.compliance:run", "distribution": "acme-shipgate-checks", "version": "1.2.3", "check_id": "ACME-COMPLIANCE-PII-MASKING" } ]
- Reviewers can see exactly which third-party packages contributed checks.
Operational guidance. Treat plugins like other CI dependencies: pin versions, audit transitive dependencies, and avoid enabling plugins in untrusted-input contexts unless those packages are approved by your security team. See Plugin Authoring for the contract.
The trust model is enforceable from the code. To audit:
| Claim | How to verify |
|---|---|
| No subprocess calls |
grep -rn "subprocess\|popen\|os.system" src/ returns nothing |
| No network in scanner |
grep -rn "requests\|urllib\|httpx\|httplib\|aiohttp" src/ returns nothing |
| No telemetry |
grep -rn "posthog\|mixpanel\|sentry\|telemetry" src/ returns nothing |
| YAML safe_load only |
grep -rn "yaml.load\|yaml.unsafe" src/ returns nothing |
| Path traversal rejected | pytest tests/test_inputs.py::test_mcp_loader_rejects_path_traversal |
| Plugin builtin spoof rejected | pytest tests/test_plugins.py::test_builtin_distribution_entry_points_are_skipped |
Releases are:
- Built reproducibly via
python -m build - Signed with sigstore (
sigstore sign) —.sigand.crtartifacts ship with the release - Published to PyPI via trusted publishing (OIDC; no long-lived credentials)
- Accompanied by a CycloneDX SBOM (
agents-shipgate-sbom.json) attached to the GitHub release
Verify the signature on a downloaded artifact:
sigstore verify identity \
--bundle agents_shipgate-0.2.0.tar.gz.sigstore \
--cert-identity 'https://github.com/ThreeMoonsLab/agents-shipgate/.github/workflows/release.yml@refs/tags/v0.2.0' \
--cert-oidc-issuer 'https://token.actions.githubusercontent.com' \
agents_shipgate-0.2.0.tar.gz- We don't certify agent safety or compliance. Findings are evidence; the release decision belongs to you.
- We don't catch every risky tool. Substring-named risks, dynamically-built tool surfaces, and runtime-only behavior all live outside the static analysis surface.
- We don't fix findings. Recommendations are suggestions for the reviewer, not prescriptions.
If you find a check that's wrong (false positive or false negative), please open an issue tagged false-positive or false-negative — that's how the catalog improves.
Agents Shipgate · Apache-2.0 · maintained by Three Moons Lab · Report a false positive
Getting started
Reference
Workflows
Extending
Project