v0.16.0
Forge v0.16.0 — AWS Bedrock SigV4 outbound, platform admission control, W3C trace propagation into subprocess skills
Forge v0.16.0 ships four substantial additions to the open-source AI agent runtime: AWS Bedrock SigV4 outbound signing with symmetric OpenAI + Anthropic wire-format support, an opt-in platform admission hook that lets a control plane gate new invocations on per-agent cost / quota ceilings, W3C trace-context propagation into skill subprocesses so OTel-instrumented CLIs nest their spans under the agent's tool.<name> span, and workflow correlation split into definition + execution IDs matching the GitHub Actions / Tekton / Argo industry pattern.
This release also adds three new runtime spans (auth.verify, channel.<adapter>.deliver, schedule.fire), a Skill Builder edit mode for iterating on attached skills from the web dashboard, opt-in workflow-header auto-propagation on allow-listed hosts, fail-loud DB mode for guardrails, an operator-visible surface for FWS-8 audit payload capture, and a consolidated redact pass that unifies the vendor-secret scrub across audit, guardrail evidence, and OTel span content.
Highlights
- AWS Bedrock SigV4 outbound (#202). New
model.auth_scheme: aws_sigv4+model.aws_regionfields onModelRef. A hand-rolled ~250 LOC stdlib-only SigV4 RoundTripper wraps the LLM client'shttp.Transportand skips the defaultAuthorization: Bearer/x-api-keyheaders. Symmetric across theopenaiandanthropicproviders — pick whichever wire format the Bedrock endpoint speaks. Credentials fromAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN. Matches the inbound-auth posture (forge-core/auth/providers/aws_sigv4) — same no-aws-sdk-go-v2policy that keeps the binary flat. - Anthropic-format Custom URLs (#202 Phase 1).
forge initwizard's "Custom URL" option now asks whether the endpoint speaks OpenAI Chat Completions or Anthropic Messages wire format and scaffolds the matching provider + base-URL env.forge.yamlnever carriesprovider: "custom". Covers Bedrock's Anthropic passthrough and Anthropic-compatible proxies alongside the existing OpenRouter / vLLM / litellm / Together.ai path. - Platform admission hook (#201). Opt-in pre-dispatch gate that asks a platform API whether to admit each new inbound A2A invocation. Engaged when both
FORGE_ADMISSION_URLandFORGE_PLATFORM_TOKENare set. At most one call per agent per 5s (baked cache); denies return HTTP 402 Payment Required with aRetry-Afterderived from the platform'sreset_at. Fail-open everywhere — network / 4xx / 5xx / parse errors log one warn line and admit, so a platform outage never blocks traffic. Distinct from 401 (auth failed) and 429 (rate limiter). Emitstask_admission_deniedaudit events and anadmission.checkOTel span sibling ofauth.verify. - Subprocess W3C trace-context propagation (#182). Skill and tool subprocesses now receive
TRACEPARENT,TRACESTATE, andBAGGAGEenv vars derived from the parent agent's active span, plus a curatedOTEL_*SDK config subset. OTel-instrumented binaries (infil, an LLM CLI, a Python service, any tool that readsTRACEPARENT) nest their spans under the agent'stool.<name>span instead of starting a fresh root.OTEL_EXPORTER_OTLP_HEADERSis deliberately excluded — collector auth tokens must be declared via SKILL.mdenv.optional. - Binary-runtime skills (#182). New
metadata.forge.runtime: binaryin the SKILL.md schema. Binary skills exec the firstmetadata.forge.requires.binsentry directly (resolved viaexec.LookPath) — no bash fork, no materialized script.runtime: script(or empty) keeps the legacy path. - Workflow correlation split (#185).
X-Workflow-Idnow carries the workflow DEFINITION id (stable across every run); newX-Workflow-Execution-Idcarries the per-run instance id. Both surface as top-level audit fields (workflow_id,workflow_execution_id). SIEM consumers answer both "every event in this specific run" (join onworkflow_execution_id) AND "top failing workflows over time" (group byworkflow_id) without joining on opaque ids. Industry precedent: GitHub Actions (workflow + workflow_run_id), Tekton (Pipeline + PipelineRun), Argo (Workflow + WorkflowRun). - Workflow header auto-propagation on allow-listed hosts (#186). New
workflow_propagation.allowed_hostsblock inforge.yaml. Hosts on the allow-list automatically receiveX-Workflow-Id/X-Workflow-Execution-Id/X-Workflow-Stage-Id/X-Workflow-Step-Id/X-Invocation-Callerfrom the current request context on every built-in HTTP tool call — no per-tool code change. Non-allow-listed hosts stay opt-in so workflow identity never leaks to third-party APIs. - Three new runtime spans (#187).
auth.verifywraps the auth chain'sVerifycall so JWKS / STS / IAP / Graph HTTP calls nest under it instead of appearing as orphan roots.channel.<adapter>.deliverwraps every channel adapter's per-message handler (Slack / Telegram / Teams); the internal A2A POST injectstraceparentso thea2a.tasks/sendspan nests under deliver — operators finally answer "Slack→agent latency" from the flame graph alone.schedule.firewraps the file-backend scheduler. - Skill Builder edit mode (#193). The web dashboard's Skill Builder can now iterate on an already-attached custom skill instead of only creating new ones. New "Skills attached to this agent" panel lists each
skills/<name>/SKILL.md; Edit loads current SKILL.md + helper scripts, primes the chat, and switches the LLM to an edit-mode prompt (preserves## Tool: <name>headings, defaults to minimal patches, emits a**Changed:**summary). Monaco diff modal shows editor-state vs disk side-by-side before save. - Guardrails DB fail-loud + operator surface (#166). New
FORGE_GUARDRAILS_DB_REQUIRED=trueenv var: when DB mode is selected and the Mongo connect fails, the runner returns a non-nil startup error instead of silently downgrading to file mode. Newforge guardrails seed-defaultssubcommand printsDefaultStructuredGuardrailsas JSON suitable for piping into MongoDB. Newforge guardrails validate-dbsubcommand reports on baseline coverage (PII, jailbreak threshold, secret-pattern rule count, gate enablement) and exits non-zero on missing document. One-shot warning when bothFORGE_GUARDRAILS_DBandguardrails.jsonare present. - Audit payload capture: operator surface + consolidated redact pass (#163). FWS-8 raw-payload capture is now configurable from
forge.yamlandFORGE_AUDIT_CAPTURE_*env vars, closing the gap that previously required a code change to enable capture in a container deployment. New sharedPrepareCapturedContenthelper — the FWS-8 hooks, guardrail evidence pipeline, and OTel span content pipeline now all delegate to one vendor-secret regex scrub instead of maintaining three copies.
What's new
AWS Bedrock SigV4 outbound (#202)
Bedrock uses AWS SigV4 signing instead of a static API key, so model.auth_scheme: aws_sigv4 swaps the default header for a hand-rolled SigV4 signature over the outbound HTTP request. Symmetric across the openai and anthropic providers:
model:
provider: anthropic # or openai, for Bedrock's OpenAI compat
name: anthropic.claude-sonnet-4-20250514-v1:0
base_url: https://bedrock-runtime.us-east-1.amazonaws.com
auth_scheme: aws_sigv4
aws_region: us-east-1Credentials come from the standard AWS env chain: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, optional AWS_SESSION_TOKEN. Region falls back to AWS_REGION env when aws_region is unset. The signer matches the inbound-auth posture in forge-core/auth/providers/aws_sigv4 — same stdlib-only crypto, no aws-sdk-go-v2 dependency (which would have added ~5 MB to a binary that recently hit 88 MB). The signing algorithm is ~250 LOC of crypto/hmac + crypto/sha256 + encoding/hex.
When AuthScheme is aws_sigv4:
- Anthropic client skips
x-api-key, keepsanthropic-version. - OpenAI client skips
Authorization: Bearer, keepsOpenAI-Organization. http.Client.Transportis wrapped with the SigV4 signer.- Configured
APIKeyis ignored on this path.
Empty AuthScheme preserves the pre-#202 contract byte-for-byte — all existing Anthropic and OpenAI deployments see zero behavior change.
Deferred (tracked separately):
- Web identity / IRSA / EC2 metadata credential resolution. Today the credential getter reads env only; most Bedrock deployments set AWS env vars at the platform layer (IRSA env injection, sidecar credential fetcher,
AWS_PROFILEresolution before launch). - Bedrock-specific URL / body rewriting (
POST /model/<id>/invokepath +anthropic_versionbody field + event-stream framing) is tracked under #205. Operators today front Bedrock with a Bedrock-compat proxy that handles protocol translation (litellm) when the model doesn't expose the OpenAI or Anthropic wire shape. forge init"AWS Bedrock" first-class wizard option (Phase 3 in the issue). The Custom path with shape-picker covers the configuration; the dedicated Bedrock option is pure UX polish.
Reference: docs/core-concepts/runtime-engine.md, docs/reference/forge-yaml-schema.md.
Platform admission hook (#201)
Forge measures LLM token usage per call and per invocation (FWS-3) so a platform can compute a spend ceiling externally. The admission hook lets the platform tell the agent process to stop accepting new invocations when that ceiling is hit — distinct from auth (HTTP 401) and from the per-IP rate limiter (HTTP 429).
The hook is off by default. Self-hosted deploys see no change. Engaged when both env vars are set:
| Env var | Behavior |
|---|---|
FORGE_ADMISSION_URL |
Platform admission endpoint. Unset → admission off. |
FORGE_PLATFORM_TOKEN |
Bearer token sent on every admission call. Unset → admission off + warn at startup. |
Existing tenancy env vars from #157 are forwarded as request headers when set (FORGE_ORG_ID → Org-Id, FORGE_WORKSPACE_ID → Workspace-Id).
Wire contract:
GET /v1/admission?agent_id=my-agent HTTP/1.1
Authorization: Bearer <FORGE_PLATFORM_TOKEN>
Org-Id: <FORGE_ORG_ID>
Workspace-Id: <FORGE_WORKSPACE_ID>
{
"decision": "admit" | "deny",
"reason": "cost_limit_exceeded",
"scope": "agent" | "workspace" | "org",
"window": "daily",
"reset_at": "2026-06-28T14:00:00Z"
}Deny → HTTP 402 Payment Required with Retry-After derived from reset_at and a structured body. Fail-open everywhere: network errors, 4xx, 5xx, body parse failure, unknown decision value → log one warn line + admit + cache the admit for the full 5s TTL (so a platform outage produces one call per agent per 5s, not a flood).
Emits task_admission_denied audit events and opens an admission.check OTel span as a sibling of auth.verify. The forge.admission.fallback=true span attribute marks admits forced by a call failure — alerts on that attribute surface platform outage rate even though no caller observes a deny.
Reference: docs/security/admission.md.
Subprocess W3C trace-context propagation + binary-runtime skills (#182)
Every skill invocation is now a span nested under the agent's tool.<name> span. Skill and tool subprocesses receive the parent span's TRACEPARENT / TRACESTATE / BAGGAGE env vars plus a curated OTEL_* SDK config subset (OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL, OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG, OTEL_RESOURCE_ATTRIBUTES).
OTel-instrumented binaries (infil, an LLM CLI, a Python service, any tool that reads TRACEPARENT) nest their spans under the agent's tool.<name> span instead of starting a fresh root. OTEL_EXPORTER_OTLP_HEADERS is deliberately excluded from the passthrough — collector auth tokens are treated as secrets and must be declared via SKILL.md env.optional like every other credential.
New metadata.forge.runtime: binary in the SKILL.md schema. Binary skills exec the first metadata.forge.requires.bins entry directly (resolved via exec.LookPath) — no bash fork, no materialized script file. runtime: script (or empty) keeps the legacy behavior.
When tracing is off the global propagator is a no-op composite — subprocess env is byte-identical to pre-#182 deploys.
Reference: docs/core-concepts/observability-tracing.md, docs/skills/writing-custom-skills.md.
Workflow definition vs execution split (#185)
The previously-overloaded X-Workflow-ID header now carries the workflow DEFINITION id (stable across every run); a new X-Workflow-Execution-ID header carries the per-run instance id. Both surface as top-level fields on every audit event under a workflow run (workflow_id, workflow_execution_id), so SIEM consumers answer both "show me every event in this specific run" (join on workflow_execution_id) AND "top failing workflows" / "latency by workflow definition" (group by workflow_id) without joining on opaque ids.
Industry precedent: GitHub Actions (workflow + workflow_run_id), Tekton (Pipeline + PipelineRun), Argo (Workflow + WorkflowRun).
Both fields use omitempty — direct A2A invocations without orchestrator headers continue to emit byte-identical JSON to pre-#185 consumers. AuditSchemaVersion remains "1.0".
Workflow header auto-propagation on allow-listed hosts (#186)
Adds a workflow_propagation.allowed_hosts block to forge.yaml. Hosts matching the allow-list automatically receive the workflow correlation headers from the current request context when invoked from any built-in HTTP tool — no per-tool code change needed.
workflow_propagation:
allowed_hosts:
- "*.internal.example.com"
- "agents.example.com"Wildcard semantics mirror the egress allow-list (exact + *.suffix.com, port-stripped, lowercase-normalized). Wildcards match strictly-deeper subdomains and refuse the apex — *.agents.internal does NOT match the bare agents.internal. Empty config short-circuits and returns the underlying transport identity-equal, zero overhead per request on the default-deploy path.
Hosts not on the list keep the pre-#186 opt-in behavior; the headers stay off so workflow identity never leaks to third-party APIs.
Three new runtime spans: auth.verify, channel.<adapter>.deliver, schedule.fire (#187)
All three use the existing global Tracer() and respect the off-by-default tracing posture — when tracing is disabled the no-op tracer makes them zero-allocation.
auth.verifywraps theProvider.Chain.Verifycall. Provider outbound HTTP calls (JWKS / STS / IAP / Graph) now nest under it instead of appearing as orphan roots. Attributes:forge.auth.provider,forge.auth.token_kind,forge.auth.decision,forge.auth.user_id/org_idon success,forge.auth.fail_reasonon failure.channel.<adapter>.deliverwraps the per-message handler in every channel adapter (Slack / Telegram / Teams). The internal A2A POST injects the W3Ctraceparentvia the global propagator, so the downstreama2a.tasks/sendspan nests under the deliver span. Attributes:forge.channel.adapter,forge.channel.target,forge.channel.message_id,forge.channel.user_id. Highest user-visible payoff of the three — operators can now answer "Slack→agent latency" from the flame graph alone.schedule.firewrapsScheduler.firein the file backend. K8s-backend dispatch is out of scope for this pass — the trigger Pod is a separate curl-based Pod and needstraceparentinjected into the rendered CronJob YAML atforge packagetime (follow-up).
Status=Error on the failure path keeps error-rate dashboards consistent across span types.
Reference: docs/core-concepts/observability-tracing.md.
Skill Builder edit mode (#193)
The dashboard's Skill Builder can now iterate on an already-attached custom skill instead of only creating new ones. A new Skills attached to this agent panel lists each skills/<name>/SKILL.md discovered on disk; clicking Edit loads its current SKILL.md and helper scripts into the editor, primes the chat with the existing content, and switches the LLM call to an edit-mode prompt that instructs it to preserve ## Tool: <name> headings, default to minimal patches, and emit a **Changed:** summary.
A Preview changes Monaco diff modal shows editor-state vs disk side-by-side before save. Confirm save overwrites the existing skill directory in place; helper scripts dropped during the edit are removed from disk so the runtime stops discovering them. A Restart agent banner appears after a successful edit-mode save because the running agent's tool registry is captured at startup and not live-mutated.
New endpoints:
GET /api/agents/{id}/skill-builder/skills→[]CustomSkillSummaryGET /api/agents/{id}/skill-builder/skills/{name}→CustomSkillContentPOST /api/agents/{id}/skill-builder/chatacceptsmode: "edit"+editing_namePOST /api/agents/{id}/skill-builder/saveacceptsoverwrite: truewith matchingediting_name
All endpoints reject path-traversal, slashes, backslashes, and non-kebab-case names with 400. The script loader rejects symlinks whose resolved target escapes the skill's own directory so a malicious link to /etc/passwd never reaches the editor or LLM context.
Reference: docs/reference/web-dashboard.md, docs/skills/writing-custom-skills.md.
Guardrails DB mode fail-loud + operator surface (#166)
Three quiet behaviors in the BuildGuardrailChecker resolution ladder that mismatched what operators expect from a "production-grade guardrails" deploy are now addressable from the operator surface:
FORGE_GUARDRAILS_DB_REQUIRED=true— when DB mode is selected (FORGE_GUARDRAILS_DBset) and the Mongo connect fails, the runner logs an Error and returns a non-nil startup error instead of silently downgrading. Off by default for back-compat; recommended ON for platform deployments where DB-mode guardrails are security-critical.forge guardrails seed-defaults— printsDefaultStructuredGuardrailsas JSON suitable for piping into MongoDB. Round-trips throughmodels.StructuredGuardrailsso the output is library-consumable verbatim. Closes the "DB mode bypasses built-in defaults" footgun.forge guardrails validate-db— connects toFORGE_GUARDRAILS_DB, fetches the agent'sAgentConfigdocument, and reports on baseline coverage (PII config, jailbreak / prompt-injection / command-injection thresholds, secret-pattern rule count, core gate enablement). Warns when fewer than 5 secret-pattern rules are present or PII config is missing. Exits non-zero on missing document so CI / deployment hooks can fail rollout.
One-shot startup warning when both FORGE_GUARDRAILS_DB is set AND a guardrails.json is present in the workdir — repo readers previously saw the file and assumed it was active; in DB-mode deploys it was dead config that drifted. Warning fires exactly once per process, pointing at the specific ignored path.
DB connect timeout in NewDBGuardrailEngine trimmed from 10s to 3s — short enough that a misconfigured URI surfaces during startup, long enough to absorb DNS jitter + TLS on a healthy cluster.
Reference: docs/security/guardrails.md.
Audit payload capture: operator surface + consolidated redact pass (#163)
FWS-8 raw-payload capture (AuditPayloadCapture) is now configurable from forge.yaml and FORGE_AUDIT_CAPTURE_* env vars in addition to the existing programmatic RunnerConfig path — closing the gap that previously made the feature unusable from a container deployment without a code change.
New env vars: FORGE_AUDIT_CAPTURE_TOOL_ARGS, FORGE_AUDIT_CAPTURE_TOOL_RESULT, FORGE_AUDIT_CAPTURE_LLM_MESSAGES, FORGE_AUDIT_CAPTURE_LLM_RESPONSE, FORGE_AUDIT_CAPTURE_REDACT (default true), FORGE_AUDIT_CAPTURE_MAX_BYTES (single-knob 16 KiB default).
New forge.yaml block under audit.capture: with per-field *bool semantics (nil = fall through to env). Precedence: forge.yaml > env > default.
New Redact field on AuditPayloadCapture. ON by default. When on, captured fields run through the shared vendor-secret regex scrub (PrepareCapturedContent) before truncation, so a token an LLM glued into a cli_execute command surfaces in audit as [REDACTED], not verbatim. Set false only when a downstream sink runs its own scrubber.
New shared helper coreruntime.PrepareCapturedContent(s, redact, maxBytes). The FWS-8 capture hooks, guardrail evidence pipeline, and OTel span content pipeline now all delegate to this one helper — a fix to the regex set propagates to every content-capture path. Removes 3 independent copies of the vendor-secret regex set.
Reference: docs/security/audit-logging.md.
CLI
forge guardrails seed-defaults— printDefaultStructuredGuardrailsas JSON suitable for piping into MongoDBforge guardrails validate-db— validate an agent'sAgentConfigdocument against baseline coverage; exits non-zero when the document is missing so CI / deployment hooks can fail rollout- The
forge initinteractive wizard's "Custom URL" option gains a shape picker (OpenAI Chat Completions vs Anthropic Messages) between the URL and model phases
forge.yaml
- New
model.auth_schemefield (""|x_api_key|bearer|aws_sigv4) andmodel.aws_region(required whenauth_scheme: aws_sigv4) — issue #202 - New top-level
workflow_propagation.allowed_hostsblock — issue #186 - New
audit.capture:block with per-field*boolsemantics fortool_args,tool_result,llm_messages,llm_response,redact,max_bytes— issue #163
Environment variables
FORGE_ADMISSION_URL+FORGE_PLATFORM_TOKEN— engage the platform admission hook (both required)FORGE_GUARDRAILS_DB_REQUIRED=true— fail-loud when the guardrails Mongo connect failsFORGE_AUDIT_CAPTURE_TOOL_ARGS,FORGE_AUDIT_CAPTURE_TOOL_RESULT,FORGE_AUDIT_CAPTURE_LLM_MESSAGES,FORGE_AUDIT_CAPTURE_LLM_RESPONSE,FORGE_AUDIT_CAPTURE_REDACT,FORGE_AUDIT_CAPTURE_MAX_BYTES— audit payload capture surface (all opt-in; capture stays off by default)
Fixed
- K8s scheduler backend no longer hard-errors when
scheduler.kubernetes.service_urlis unset (#179). Pre-fix, an agent deployed in-cluster withscheduler.backend: autoand no explicitservice_urlaborted startup withkubernetes scheduler backend: scheduler.kubernetes.service_url is required, even though the build-timeschedule_manifest_stagealready knew how to default the same field. Runtime now mirrors the build-time default: whenServiceURLis empty, the constructor derives the in-cluster Service DNS usingagent_id+ resolved namespace + the runner's listen port. Explicitservice_urloverrides pass through untouched. forge initscaffoldsscheduler.backend: fileexplicitly. Previously the omitted field left the K8s-vs-file resolution to runtime auto-detection, which surprised operators reading the scaffolded yaml.forge initalways emits the env secret provider in the scaffoldedforge.yaml. Previously the block was omitted when no secrets were declared, which meant a laterforge secret sethad no provider to write into and silently no-op'd.- Audit
SequenceCounterinstalls before auth soauth_verifylandsseq=1andsession_startlandsseq=2(#174). Previously the counter was installed inside the auth middleware, soauth_verifyevents emitted with an emptyseqfield. tool_exec+session_endaudit events now stampseq. Previously theEmitToolExecandEmitSessionEndpaths bypassedEmitFromContextand skipped the counter increment; consumers detecting gaps saw phantom holes in the sequence.
Audit-event schema
AuditSchemaVersion remains "1.0". All new fields are additive:
workflow_execution_id— top-level,omitempty— fromX-Workflow-Execution-IDtask_admission_denied— new event withfields.reason/scope/window/reset_at/cached- FWS-8 capture fields (
args,result,prompt_messages,completion_text) surface ontool_exec/llm_callwhen the corresponding capture flag is on; absent otherwise
Consumers ignoring unknown keys continue to work unchanged.
Documentation
docs/security/admission.md— new operator reference for the platform admission hook: wire contract, fail-open posture, audit + spandocs/core-concepts/runtime-engine.md— new Custom URL Endpoints + AWS Bedrock (SigV4 outbound) sectionsdocs/core-concepts/observability-tracing.md—auth.verify,channel.<adapter>.deliver,schedule.fire,admission.checkspan sections; subprocess trace propagationdocs/security/audit-logging.md—task_admission_deniedevent; FWS-8 capture env surfacedocs/reference/forge-yaml-schema.md—model.auth_scheme/aws_region,workflow_propagation.allowed_hosts,audit.capture:docs/reference/cli-reference.md—forge guardrails seed-defaults/validate-db; wizard shape picker
Closed issues
- #163 — audit payload capture operator surface (env + yaml) + consolidated redact pass
- #166 — guardrails DB fail-loud +
seed-defaults/validate-db+ exclusivity warning - #174 —
SequenceCounterinstalled before auth;tool_exec/session_endstampseq - #179 — K8s scheduler
service_urldefault at runtime - #182 — subprocess W3C trace-context propagation + binary-runtime skills
- #185 — split
X-Workflow-IDinto definition + execution ids - #186 — opt-in workflow-header auto-propagation on allow-listed hosts
- #187 —
auth.verify,channel.<adapter>.deliver,schedule.fireruntime spans - #193 — Skill Builder edit mode for iterating on attached skills
- #201 — platform admission hook (opt-in pre-dispatch quota gate)
- #202 — Anthropic-format Custom URLs + AWS Bedrock SigV4 outbound
Upgrading from v0.15.x
Forge v0.16.0 is backwards-compatible with v0.15.x deployments. The new admission hook, workflow-execution ID, subprocess trace propagation, workflow-header auto-propagation, audit payload capture surface, and Bedrock SigV4 support are all opt-in — deployments that don't set the corresponding env vars / yaml fields keep emitting the pre-v0.16 shape verbatim.
To opt into the platform admission hook on an existing deployment:
- Deploy the platform-side admission endpoint (
GET /v1/admission?agent_id=<id>returning{decision, reason, scope, window, reset_at}). - Set
FORGE_ADMISSION_URLandFORGE_PLATFORM_TOKENon the agent process. Both must be set — one without the other logs a warn and disables the hook. - Optionally set
FORGE_ORG_ID/FORGE_WORKSPACE_IDso the outbound admission call carriesOrg-Id/Workspace-Idheaders. - No
forge.yamlchange required.
To point Forge at AWS Bedrock:
- Set
model.providertoanthropicoropenaidepending on which wire format the Bedrock endpoint speaks. - Set
model.base_url: https://bedrock-runtime.<region>.amazonaws.com,model.auth_scheme: aws_sigv4,model.aws_region: <region>. - Set
AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEY(+AWS_SESSION_TOKENfor temporary credentials) in the environment. - For Bedrock models that don't expose the OpenAI or Anthropic wire shape, front Bedrock with a compat proxy (e.g. litellm) until #205 lands native URL/body rewriting.
Full changelog
git log v0.15.0..v0.16.0 --oneline in this repository, or browse v0.15.0...v0.16.0 on GitHub.