概述
资源挂载是七牛沙箱额外提供的开发者能力,适合在 AI Agent、代码审查、自动化构建和代码迁移等场景中安全地使用外部资源。
创建沙箱时可以通过 resources 参数声明需要挂载的外部资源:
| 参数 | 能力 | 说明 |
|---|---|---|
resources |
资源挂载 | 沙箱启动前由平台准备外部资源,并挂载到沙箱内指定路径 |
当前 resources 支持 GitHub 仓库资源和 Kodo 存储桶资源。访问外部资源需要的凭证尽量由平台侧持有,不直接暴露给沙箱内进程。
支持的资源类型
GitHub 仓库资源
GitHub 仓库资源用于在沙箱启动前预拉取仓库快照,并挂载到沙箱内指定路径。适合代码审查、自动化构建、AI Agent 改代码等场景。
| 字段 | 是否必填 | 说明 |
|---|---|---|
type |
是 | 资源类型;GitHub 仓库资源填写 github_repository |
url |
是 | GitHub 仓库地址,支持 HTTPS 地址,或 git@github.com:owner/repo.git 这种 GitHub SSH 风格地址;平台会统一转为 HTTPS 处理 |
mount_path |
是 | 沙箱内挂载路径,必须是绝对路径,且同一个沙箱内不能重复 |
authorization_token |
是 | 访问该仓库的 GitHub Token;同一个沙箱内多个 GitHub 仓库资源当前必须使用同一个 Token |
如果创建沙箱时传入 github_repository 资源,平台会使用资源中的 authorization_token 预拉取仓库,并自动派生运行时 GitHub 密钥注入。沙箱内进程不需要、也无法直接读取真实 Token。
Kodo 存储桶资源
Kodo 存储桶资源用于把七牛云对象存储 Bucket 通过 NFS 挂载到沙箱内指定路径。适合让沙箱直接读取数据集、构建产物、模型文件、日志归档等对象存储内容。
Kodo 资源只支持使用七牛 AK/SK 鉴权创建沙箱;仅使用沙箱 API Key 的创建请求不支持挂载 Kodo 资源。凭证用于平台侧访问 Bucket,不会以明文暴露给沙箱内进程。
| 字段 | 是否必填 | 说明 |
|---|---|---|
type |
是 | 资源类型;Kodo 存储桶资源填写 kodo |
bucket |
是 | Kodo Bucket 名称 |
mount_path |
是 | 沙箱内挂载路径,必须是绝对路径,且同一个沙箱内不能重复 |
prefix |
否 | Bucket 内的对象 key 前缀;传入后只暴露该前缀下的内容。服务端会去掉首尾 / 并规范化路径 |
read_only |
否 | 是否只读挂载。显式传 true 时只校验读取权限;未传或传 false 时平台会尝试校验写权限,如果 AK/SK 无写权限,会自动改为只读挂载 |
创建沙箱时传入 kodo 资源后,平台会校验 Bucket 可访问性,并为沙箱创建 NFS 代理挂载。沙箱内进程只看到 mount_path 下的文件系统视图,看不到 AK/SK。
工作原理
沙箱启动前:
外部资源 ── 平台使用凭证准备资源 ── 挂载到沙箱内 mount_path
核心行为:
- 资源在沙箱启动前准备完成,启动后可直接访问
mount_path - 凭证由平台侧持有,不以环境变量、文件或命令参数形式进入沙箱
- GitHub 仓库资源会自动派生运行时 GitHub 注入,后续
git pull、git push等操作可继续鉴权 - Kodo 存储桶资源通过平台侧 NFS 代理挂载;
prefix可限制沙箱只能看到 Bucket 中某个前缀下的内容 - Kodo 挂载的读写能力取决于 AK/SK 权限和
read_only设置;无写权限时平台会自动降级为只读挂载
当
resources中包含github_repository时,不要再显式传入type: github的injections。服务端会根据authorization_token自动派生 GitHub 注入;如果同时显式传入,会返回400 github_repository resources do not support explicit github injections。
使用 Go SDK 挂载资源
以下示例基于 七牛 Go SDK v7.26.13+。v7.26.13 起,Go SDK 支持在创建沙箱时挂载 Kodo bucket 资源。
挂载 GitHub 仓库
package main
import (
"context"
"log"
"os"
"github.com/qiniu/go-sdk/v7/sandbox"
)
func stringPtr(s string) *string { return &s }
func main() {
ctx := context.Background()
apiKey := requiredEnv("QINIU_API_KEY")
githubToken := requiredEnv("GITHUB_TOKEN")
client, err := sandbox.NewClient(&sandbox.Config{
APIKey: apiKey,
Endpoint: os.Getenv("QINIU_SANDBOX_API_URL"),
})
if err != nil {
log.Fatal(err)
}
sb, _, err := client.CreateAndWait(ctx, sandbox.CreateParams{
TemplateID: "base",
Resources: &[]sandbox.SandboxResourceSpec{
{
GitRepository: &sandbox.GitRepositoryResource{
Type: sandbox.GitRepositoryTypeGithub,
URL: "https://github.com/owner/private-repo.git",
MountPath: "/workspace/repo",
AuthorizationToken: stringPtr(githubToken),
},
},
},
})
if err != nil {
log.Fatal(err)
}
defer sb.Kill(ctx)
result, err := sb.Commands().Run(ctx, "cd /workspace/repo && git status --short")
if err != nil {
log.Fatal(err)
}
log.Println(result.Stdout)
}
func requiredEnv(name string) string {
value := os.Getenv(name)
if value == "" {
log.Fatalf("%s is required", name)
}
return value
}
这个例子中:
/workspace/repo在沙箱启动后已经包含仓库内容GITHUB_TOKEN不会出现在沙箱环境变量或文件系统中- 后续在
/workspace/repo执行git pull、git push时,会复用平台自动派生的 GitHub 注入
挂载 Kodo 存储桶
Go SDK 的 sandbox.KodoResource 不包含 access_key / secret_key 字段。创建带 Kodo resource 的沙箱时,需要在 sandbox.Config.Credentials 中配置七牛 AK/SK,SDK 会为创建请求添加 Qiniu 签名鉴权。
package main
import (
"context"
"log"
"os"
"github.com/qiniu/go-sdk/v7/auth"
"github.com/qiniu/go-sdk/v7/sandbox"
)
func stringPtr(s string) *string { return &s }
func boolPtr(v bool) *bool { return &v }
func main() {
ctx := context.Background()
client, err := sandbox.NewClient(&sandbox.Config{
APIKey: requiredEnv("QINIU_API_KEY"),
Endpoint: os.Getenv("QINIU_SANDBOX_API_URL"),
Credentials: auth.New(
requiredEnv("KODO_ACCESS_KEY"),
requiredEnv("KODO_SECRET_KEY"),
),
})
if err != nil {
log.Fatal(err)
}
sb, _, err := client.CreateAndWait(ctx, sandbox.CreateParams{
TemplateID: "base",
Resources: &[]sandbox.SandboxResourceSpec{
{
Kodo: &sandbox.KodoResource{
Bucket: "my-bucket",
MountPath: "/mnt/kodo",
Prefix: stringPtr("datasets/demo"),
ReadOnly: boolPtr(true),
},
},
},
})
if err != nil {
log.Fatal(err)
}
defer sb.Kill(ctx)
result, err := sb.Commands().Run(ctx, "find /mnt/kodo -maxdepth 2 -type f | head")
if err != nil {
log.Fatal(err)
}
log.Println(result.Stdout)
}
func requiredEnv(name string) string {
value := os.Getenv(name)
if value == "" {
log.Fatalf("%s is required", name)
}
return value
}
这个例子中:
/mnt/kodo在沙箱启动后已经是 Kodo bucket 的文件系统视图KODO_ACCESS_KEY和KODO_SECRET_KEY只用于 SDK 对创建请求签名,不会写入 resource JSON,也不会进入沙箱ReadOnly: true会让平台只校验读取权限,并以只读方式挂载
REST API 示例
创建沙箱并挂载 GitHub 仓库资源:
curl -X POST "$QINIU_SANDBOX_API_URL/sandboxes" \
-H "X-API-Key: $QINIU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateID": "base",
"resources": [
{
"type": "github_repository",
"url": "https://github.com/owner/private-repo.git",
"mount_path": "/workspace/repo",
"authorization_token": "'"$GITHUB_TOKEN"'"
}
]
}'
创建沙箱并挂载 Kodo 存储桶资源:
curl -X POST "$QINIU_SANDBOX_API_URL/sandboxes" \
-H "X-API-Key: $QINIU_API_KEY" \
-H "Authorization: Qiniu <SignedToken>" \
-H "Content-Type: application/json" \
-d '{
"templateID": "base",
"resources": [
{
"type": "kodo",
"bucket": "my-bucket",
"mount_path": "/mnt/kodo",
"prefix": "datasets/demo",
"read_only": true
}
]
}'
其中 SignedToken 需要用七牛 AK/SK 生成。只带 X-API-Key、不带 AK/SK 签名的请求不支持创建 Kodo 资源沙箱。
这个例子中:
- 沙箱启动后可以通过
/mnt/kodo访问my-bucket中datasets/demo前缀下的对象 - AK/SK 只用于请求签名,不会出现在请求 JSON、沙箱环境变量或文件系统中
read_only: true会让平台只校验读取权限,并以只读方式挂载
同一个沙箱也可以同时挂载 GitHub 仓库资源和 Kodo 存储桶资源,只要每个资源的 mount_path 不重复:
{
"templateID": "base",
"resources": [
{
"type": "github_repository",
"url": "https://github.com/owner/private-repo.git",
"mount_path": "/workspace/repo",
"authorization_token": "ghp_xxx"
},
{
"type": "kodo",
"bucket": "my-bucket",
"mount_path": "/workspace/data",
"prefix": "datasets/demo"
}
]
}
常见工作流
启动即拥有代码
适合代码审查、构建测试、仓库内容分析:
- 创建沙箱时传入
github_repository资源 - 平台预拉取仓库并挂载到
mount_path - Agent 直接在挂载目录内运行测试、分析或修改代码
修改后推送回仓库
适合自动修复、批量迁移、文档更新:
- 创建沙箱时传入
github_repository资源 - Agent 在挂载目录中修改代码
- Agent 配置 Git 作者信息并提交
- Agent 直接执行
git push
示例:
cd /workspace/repo
git checkout -b feature/auto-fix
git config user.name "AI Bot"
git config user.email "bot@example.com"
git add .
git commit -m "fix: update generated files"
git push -u origin feature/auto-fix
读取对象存储数据
适合数据分析、模型推理、批量处理对象存储中的文件:
- 创建沙箱时传入
kodo资源 - 如果只需要读取,建议显式传入
read_only: true - Agent 直接从
mount_path读取文件
示例:
ls -lah /mnt/kodo
python /workspace/repo/scripts/analyze.py --input /mnt/kodo/input.jsonl
写入对象存储结果
适合把沙箱内生成的报告、构建产物或处理结果写回 Kodo:
- 创建沙箱时使用有写权限的 AK/SK 签名鉴权
- 不传
read_only,或传入read_only: false - Agent 把结果写入
mount_path下的目标路径
如果平台检测到 AK/SK 没有写权限,会自动按只读挂载处理。此时写入操作会在沙箱内失败,需要换用有写权限的 AK/SK 后重新创建沙箱。
限制与注意事项
resources最多 20 项- 所有
mount_path必须是绝对路径,不能重复,不能包含路径穿越 github_repository.authorization_token当前必填,即使目标仓库是公开仓库- 同一个沙箱内多个 GitHub 仓库资源必须使用同一个
authorization_token - 使用
github_repository资源时,不要额外显式传入 GitHub 注入 - GitHub 仓库资源使用缓存快照,不保证每次创建沙箱都拉取最新 HEAD;如果任务依赖最新代码,请在挂载目录内执行
git pull - 如果需要最小化权限,GitHub 建议使用 Fine-grained PAT,并只授予目标仓库需要的读写权限
kodo.bucket和kodo.mount_path均为必填;kodo.prefix和kodo.read_only可选- 创建带
kodo资源的沙箱必须使用七牛 AK/SK 鉴权;仅使用沙箱 API Key 不支持 Kodo 资源 - API 服务必须配置
S3_KODO_ENDPOINT,否则创建带kodo资源的沙箱会失败 kodo.prefix不能包含路径穿越;服务端会去掉首尾/,例如/datasets/demo/会规范化为datasets/demo- Kodo 资源会在创建沙箱时校验 Bucket 可访问性;显式
read_only: true时只校验读取权限,未显式只读时还会探测写权限 - Kodo 存储桶通过 NFS 挂载,适合文件式访问对象存储;对一致性、目录遍历和大量小文件访问的性能预期应按对象存储和 NFS 代理特性评估