关于 tigris-security-access-control
用于配置和审计 Tigris 对象存储访问权限的技能,涵盖访问密钥生命周期、存储桶角色与可见性、CORS 规则及预签名 URL 安全使用。
主要功能
- 01创建、分配、轮换和撤销密钥
- 02按存储桶和角色限定密钥
- 03配置并验证 CORS
- 04设置存储桶公开或私有访问
- 05检查预签名 URL 安全措施
- 06审计存储访问设置
适用场景
- 01为应用服务器授予存储桶读写权限
- 02为浏览器上传配置 CORS
- 03轮换可能泄露的访问密钥
- 04检查存储凭据和访问策略
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ tigrisdata/ skills --skill tigris-security-access-control安装后在 Claude Code 中输入/tigris-security-access-control确认已加载。
附带文件metadata.jsonREADME.md
详细介绍
Tigris 安全与访问控制
为 Tigris 对象存储配置访问密钥、CORS 规则、存储桶可见性和预签名 URL 安全。涵盖密钥生命周期管理、基于角色的访问控制和安全审计。
前置条件
在进行任何操作之前,如果尚未安装 Tigris CLI,请先安装:
tigris help || npm install -g @tigrisdata/cli
如果需要安装,请告诉用户:“我正在安装 Tigris CLI(@tigrisdata/cli),以便我们使用 Tigris 对象存储。”
快速参考
| 操作 | 命令 |
|---|---|
| 创建密钥 | tigris access-keys create "my-key" |
| 列出密钥 | tigris access-keys list |
| 分配给存储桶 | tigris access-keys assign <tid> --bucket <name> --role Editor |
| 撤销密钥 | tigris access-keys delete <tid> |
| 设置 CORS | tigris buckets cors set <bucket> --config cors.json |
| 获取 CORS | tigris buckets cors get <bucket> |
| 移除 CORS | tigris buckets cors delete <bucket> |
访问密钥生命周期
创建
tigris access-keys create "production-app-key"
# Output:
# Access Key ID: tid_xxx
# Secret Access Key: tsec_yyy ← shown ONLY once, save immediately
分配给存储桶
# Editor: read + write + delete
tigris access-keys assign tid_xxx --bucket my-app-uploads --role Editor
# ReadOnly: read only
tigris access-keys assign tid_xxx --bucket my-app-uploads --role ReadOnly
| 角色 | 读取 | 写入 | 删除 | 适用场景 |
|---|---|---|---|---|
Editor | 是 | 是 | 是 | 上传或修改文件的应用服务器 |
ReadOnly | 是 | 否 | 否 | 只读取或提供文件的服务 |
尽量缩小密钥权限范围
为不同用途创建单独的密钥:
# Key for the app server (read/write to uploads bucket)
tigris access-keys create "app-server"
tigris access-keys assign tid_app --bucket app-uploads --role Editor
# Key for the CDN/read service (read-only)
tigris access-keys create "cdn-reader"
tigris access-keys assign tid_cdn --bucket app-uploads --role ReadOnly
# Key for backups (write to backup bucket only)
tigris access-keys create "backup-writer"
tigris access-keys assign tid_bak --bucket app-backups --role Editor
轮换密钥(零停机)
# 1. Create new key
tigris access-keys create "production-app-key-v2"
tigris access-keys assign tid_new --bucket my-app-uploads --role Editor
# 2. Update application environment with new key
# (deploy with new TIGRIS_STORAGE_ACCESS_KEY_ID / SECRET)
# 3. Verify app works with new key
# 4. Revoke old key
tigris access-keys delete tid_old
列出密钥并审计
# List all access keys
tigris access-keys list
# Check which buckets a key can access
tigris access-keys info tid_xxx
CORS 配置
基于浏览器的上传(直接上传、预签名 PUT URL)需要 CORS。
设置 CORS 规则
tigris buckets cors set my-app-uploads --config cors.json
开发环境(本地主机)
{
"CORSRules": [
{
"AllowedOrigins": ["http://localhost:3000", "http://localhost:5173"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag", "Content-Length"],
"MaxAgeSeconds": 3600
}
]
}
生产环境(指定域名)
{
"CORSRules": [
{
"AllowedOrigins": ["https://myapp.com", "https://www.myapp.com"],
"AllowedMethods": ["GET", "PUT", "HEAD"],
"AllowedHeaders": ["Content-Type", "Content-MD5", "Content-Disposition"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 86400
}
]
}
开发环境与生产环境组合
{
"CORSRules": [
{
"AllowedOrigins": [
"https://myapp.com",
"https://www.myapp.com",
"http://localhost:3000"
],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag", "Content-Length"],
"MaxAgeSeconds": 3600
}
]
}
宽松配置(允许任何来源)
{
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 86400
}
]
}
**警告:**仅对真正公开且只读的内容使用 "*" 来源。切勿允许来自任何来源的 PUT/DELETE 请求。
验证 CORS
# Check current CORS config
tigris buckets cors get my-app-uploads
# Test with curl
curl -I -H "Origin: https://myapp.com" \
-H "Access-Control-Request-Method: PUT" \
-X OPTIONS \
https://my-app-uploads.t3.storage.dev/test
公开与私有存储桶
| 设置 | 谁可以读取 | URL 访问方式 | 用途 |
|---|---|---|---|
| 私有(默认) | 仅限经过身份验证的请求 | 预签名 URL | 用户文档、敏感文件 |
| 公开 | 任何拥有 URL 的人 | 直接 URL | 静态资源、公开图片、CDN 内容 |
# Create public bucket
tigris buckets create my-public-assets --public
# Create private bucket (default)
tigris buckets create my-private-docs
预签名 URL 安全
最佳实践
| 参数 | 建议 |
|---|---|
| 有效期(下载) | 大多数场景为 5–60 分钟 |
| 有效期(上传) | 5–15 分钟 |
| 范围 | 每个文件使用一个 URL,每个 URL 仅用于一种操作 |
import { getPresignedUrl } from "@tigrisdata/storage";
// Short-lived download URL
const { data } = await getPresignedUrl("documents/report.pdf", {
operation: "get",
expiresIn: 300, // 5 minutes
});
// Short-lived upload URL with content type restriction
const { data } = await getPresignedUrl("uploads/photo.jpg", {
operation: "put",
expiresIn: 600,
contentType: "image/jpeg", // Client must upload this type
});
切勿这样做
- 将有效期设置为超过 24 小时
- 为整个存储桶前缀生成预签名 URL
- 在公开渠道分享预签名 URL(它们属于机密信息)
- 将预签名 URL 用作永久链接(请改用公开存储桶 URL)
环境变量安全
# .env (never commit this file)
TIGRIS_STORAGE_ACCESS_KEY_ID=tid_xxx
TIGRIS_STORAGE_SECRET_ACCESS_KEY=tsec_yyy
# .gitignore (must include)
.env
.env.local
.env.*.local
对于 CI/CD,请使用平台提供的密钥管理功能:
# GitHub Actions
gh secret set TIGRIS_STORAGE_ACCESS_KEY_ID
gh secret set TIGRIS_STORAGE_SECRET_ACCESS_KEY
# Vercel
vercel env add TIGRIS_STORAGE_ACCESS_KEY_ID
# Fly.io
fly secrets set TIGRIS_STORAGE_ACCESS_KEY_ID=tid_xxx
安全审计清单
- 代码中没有密钥——在仓库中搜索
tid_和tsec_ -
.env已加入.gitignore——绝不提交凭据 - 密钥已限定到存储桶——没有未分配且拥有全局访问权限的密钥
- 角色符合需求——只读服务使用
ReadOnly角色 - CORS 未过度放宽——写入方法不允许
"*"来源 - 预签名 URL 有效期较短——大多数情况下不超过 1 小时
- 已撤销未使用的密钥——不存在前团队成员或旧部署遗留的密钥
- 每个环境使用独立密钥——开发、预发布和生产环境使用不同的密钥
密钥泄露响应
如果访问密钥遭到泄露(提交到 git、出现在日志中等):
# 1. Immediately revoke the compromised key
tigris access-keys delete tid_compromised
# 2. Create a new key
tigris access-keys create "replacement-key"
tigris access-keys assign tid_new --bucket my-bucket --role Editor
# 3. Update all deployments with the new key
# (update .env, CI/CD secrets, deployment configs)
# 4. Audit access — check for unauthorized uploads/downloads
tigris ls t3://my-bucket --recursive -l | sort -k4 -r | head -50
# 5. If key was committed to git, rotate and consider the entire
# git history compromised — use git-filter-repo to remove it
关键规则
始终: 为不同环境和用途创建独立密钥 | 将密钥分配给特定存储桶,并授予所需的最低权限 | 定期轮换密钥(建议每季度一次) | 在生产环境中将 CORS 设置为特定来源 | 使用短期预签名 URL
切勿: 将密钥提交到 git | 在所有环境中使用同一个密钥 | 将 CORS 设置为 "*" 并启用写入方法 | 公开分享预签名 URL | 保留未使用的密钥
已知问题
| 问题 | 解决方法 |
|---|---|
| CORS 预检失败 | 检查 AllowedOrigins 是否包含你的确切来源(包括协议) |
| 轮换密钥后出现“访问被拒绝” | 确保新密钥已分配给具有正确角色的存储桶 |
| 密钥丢失 | 无法找回 — 创建新密钥并重新分配 |
| 浏览器上传无提示失败 | 检查 CORS 配置中的 AllowedMethods 是否包含 PUT |
相关技能
- file-storage — CLI 设置和访问密钥创建
- tigris-s3-migration — 迁移期间的 CORS 和凭据设置
官方文档
评论
支持 Markdown