Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/agents-api/sandbox-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Initial setup requires the selected template to appear in the key's team-owned t
| `400 sandbox_configuration_invalid` | The candidate build is invalid or does not match the resources |
| `503 sandbox_verification_unconfirmed` | A receipt is missing or unsettled, or a read is unconfirmed |

No provider text or credential is returned. The write and its `change` or `replace_credential` audit entry share one transaction. A replacement briefly fences provider calls, waits for helper processes to actually exit even after the caller cancelled, and verifies again before committing; a helper's exit does not prove that a remote Create settled. The fence and reads are bounded, and a failure keeps the old key and lifecycles. After the successful response, all retained-generation management uses the committed key; only then revoke the old key in E2B, never before cleanup. Template and resource changes do not drain lifecycles.
No provider text or credential is returned. The write and its `change` or `replace_credential` audit entry share one transaction. Core derives administrator provenance from the authenticated request, with the optional `X-Core-Console-Actor` header as its actor label. A replacement briefly fences provider calls, waits for helper processes to actually exit even after the caller cancelled, and verifies again before committing; a helper's exit does not prove that a remote Create settled. The fence and reads are bounded, and a failure keeps the old key and lifecycles. After the successful response, all retained-generation management uses the committed key; only then revoke the old key in E2B, never before cleanup. Template and resource changes do not drain lifecycles.

## Generation ownership and rollout

Expand Down
4 changes: 2 additions & 2 deletions contracts/agents-api/zh/sandbox-deployment.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "沙箱部署"
source: contracts/agents-api/sandbox-deployment.md
source_hash: 06a69e3d0ba245ab27c0b5d7390364a35d10fb8478e2d0f6867749b29368f980
source_hash: 9d4559f7207943ece262ed626fbc233dd16b1bb1f271e6ea440b30d26f0a0bd3
---

沙箱部署为 Core 管理的 `openai_hosted` 执行选择 Sandbox Provider、每个沙箱的资源以及不可变的 Runtime 发行版。PostgreSQL 为每个安装维护一个当前有效选择;Web 和 Core API 写入同一配置。节点文件保存其已安装副本和特定于主机的路径,且不能覆盖其资源或 Runtime。该选择独立于 Harness;部署可以保持未配置状态,既无节点,也不接受托管准入。
Expand Down Expand Up @@ -116,7 +116,7 @@ POST 会在持久保存候选配置之前对其进行验证,并且不会创建
| `400 sandbox_configuration_invalid` | 候选构建无效或与资源不匹配 |
| `503 sandbox_verification_unconfirmed` | 回执缺失或未结算,或读取未得到确认 |

不会返回提供商文本或凭据。写入操作及其 `change` 或 `replace_credential` 审计条目共用一个事务。替换操作会短暂对提供商调用设置栅栏,即使调用方已取消,也会等待辅助进程实际退出,并在提交前再次验证;辅助进程退出并不能证明远程 Create 已结算。栅栏和读取均有时间边界,失败时会保留旧密钥和生命周期。成功响应后,所有保留代次管理都使用已提交的密钥;只有在清理完成后,才能在 E2B 中撤销旧密钥,绝不能提前撤销。模板和资源更改不会排空生命周期。
不会返回提供商文本或凭据。写入操作及其 `change` 或 `replace_credential` 审计条目共用一个事务。Core 从已认证请求中派生管理员审计来源,并使用可选的 `X-Core-Console-Actor` 请求头作为操作者标签。替换操作会短暂对提供商调用设置栅栏,即使调用方已取消,也会等待辅助进程实际退出,并在提交前再次验证;辅助进程退出并不能证明远程 Create 已结算。栅栏和读取均有时间边界,失败时会保留旧密钥和生命周期。成功响应后,所有保留代次管理都使用已提交的密钥;只有在清理完成后,才能在 E2B 中撤销旧密钥,绝不能提前撤销。模板和资源更改不会排空生命周期。

## 代次所有权与推出 {#generation-ownership-and-rollout}

Expand Down
4 changes: 4 additions & 0 deletions deploy/kubernetes/BETA_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ Upstream [CI run 37126282818](https://github.com/MiniMax-AI/OpenAgentCore/action
The release adds authenticated transport registration and confirmed capability observations, daemon startup stage timings, and coalesced capability-driven scheduler hints. [Execution latency](../../docs/getting-started/operations.md#execution-latency) owns the log boundaries and limitations. Existing allocations retain their immutable template generation; new allocations use the new template only after its selection is updated through the administrative deployment API.

Validation passed focused gateway/execution/daemon regressions and race checks, isolated PostgreSQL scheduling and Worker admission/device-isolation fixtures, Runtime contract checks, static checks, the name guard, documentation checks and all translation checks. The source review found no blocking issues. Cloud build readiness and production health remain separate from real-model and suspension acceptance.

## 2026-10-06 — Sandbox template change audit

The administrative deployment update records authenticated administrator provenance before the execution owner changes the selection. This allows the template selection and its audit entry to commit together. The change adds no schema migration, SQL, Runtime wire or native dependency changes. The combined Runtime template built at `298957f7e6a2a707e2b01b75523764b4e1ff5ab5` remains compatible with this Core API correction.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"
"testing"

"github.com/MiniMax-AI/OpenAgentCore/services/core/internal/adminaudit"
"github.com/MiniMax-AI/OpenAgentCore/services/core/internal/deployment"
"github.com/MiniMax-AI/OpenAgentCore/services/core/internal/deployment/placement"
"github.com/MiniMax-AI/OpenAgentCore/services/core/internal/sandbox"
Expand All @@ -17,8 +18,12 @@ import (
func TestSandboxDeploymentChangesAuthenticateAndDecode(t *testing.T) {
deps, fakes := sandboxFakes(t)
updates, resets := 0, 0
update := func(_ context.Context, in sandbox.Selection) (deployment.View, error) {
update := func(ctx context.Context, in sandbox.Selection) (deployment.View, error) {
updates++
source, ok := adminaudit.FromContext(ctx)
if !ok || source.ValidateDeploymentMutation("change", "sandbox_deployment", "fixture-installation") != nil || source.ActorLabel != "deployment-operator" || source.CredentialID == "administrator" {
t.Fatal("deployment change lost authenticated administrator provenance")
}
if in.Provider != "e2b" || in.ExpectedGeneration != 2 || in.Configuration == nil || in.Configuration.(*e2b.DeploymentConfiguration).APIKey != "synthetic-private-key" {
t.Fatal("write-only fields were lost")
}
Expand Down Expand Up @@ -62,6 +67,7 @@ func TestSandboxDeploymentChangesAuthenticateAndDecode(t *testing.T) {
} {
r := httptest.NewRequest(tc.method, "/core/v1/sandbox"+tc.path, strings.NewReader(tc.body))
r.Header.Set("Authorization", "Bearer "+tc.token)
r.Header.Set("X-Core-Console-Actor", "deployment-operator")
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
if w.Code != tc.status || strings.Contains(w.Body.String(), "synthetic-private-key") {
Expand Down
1 change: 1 addition & 0 deletions services/core/internal/api/sandbox_deployment_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func (h *Handler) updateSandboxDeployment(w http.ResponseWriter, r *http.Request
writeDeploymentError(w, r, err)
return
}
setAdminAuditSource(r, "")
result, err := h.Sandboxes.DeploymentChanges.UpdateSandboxDeployment(r.Context(), selection)
if err != nil {
writeDeploymentError(w, r, err)
Expand Down
Loading