ไธบ AI Agent ่ฎพ่ฎก็่ชๆ็ฎกๅญ่ฏ็ฎก็ๆๅก
่ฟ่กๅจ Cloudflare Workers ไธ๏ผๆฏๆ Bitwarden ๅ ผๅฎนๅ่ฎฎ
| ๅ่ฝ | ๆ่ฟฐ |
|---|---|
| ๐ค | Machine Accounts - ไธบๆฏไธช Agent ๅๅปบ็ฌ็ซ็ๆบๅจ่ดฆๅท |
| ๐ | Projects - ๆ้กน็ฎๅ็ป็ฎก็ๅญ่ฏ |
| ๐ | Secrets - ๅฎๅ จๅญๅจ API KeyใTokenใๅฏ็ ็ญๅญ่ฏ |
| ๐ซ | Access Tokens - Agent ้่ฟ Token ่ฎฟ้ฎๅญ่ฏ |
| ๐ | Audit Logs - ่ฎฐๅฝๆๆๅญ่ฏ่ฎฟ้ฎ่กไธบ |
| ๐ | End-to-End Encryption - AES-256-GCM ๅ ๅฏๅญๅจ |
# ๅ
้ไปๅบ
git clone https://github.com/ialer/tirisfal.git
cd tirisfal
# ๅฎ่ฃ
ไพ่ต
npm install
# ้
็ฝฎ็ฏๅขๅ้
cp .dev.vars.example .dev.vars
# ่ฎพ็ฝฎๅฏ้ฅ
wrangler secret put JWT_SECRET
wrangler secret put ENCRYPTION_KEY
# ๅๅงๅๆฐๆฎๅบ
wrangler d1 execute tirisfal-db --file=./migrations/0001_init.sql
wrangler d1 execute tirisfal-db --file=./migrations/0002_sm_tables.sql
# ้จ็ฝฒ
npm run deploynpm run devcurl -X POST https://your-worker.workers.dev/api/machine-accounts \
-H "Authorization: Bearer <user-token>" \
-H "Content-Type: application/json" \
-d '{"name": "my-agent", "description": "My AI Agent"}'curl -X POST https://your-worker.workers.dev/api/machine-accounts/<id>/token \
-H "Authorization: Bearer <user-token>"# ๅๅปบ้กน็ฎ
curl -X POST https://your-worker.workers.dev/api/projects \
-H "Authorization: Bearer <user-token>" \
-H "Content-Type: application/json" \
-d '{"name": "my-project"}'
# ๅๅปบๅญ่ฏ
curl -X POST https://your-worker.workers.dev/api/secrets \
-H "Authorization: Bearer <user-token>" \
-H "Content-Type: application/json" \
-d '{"name": "API_KEY", "value": "sk-***", "project_id": "<project-id>"}'curl "https://your-worker.workers.dev/api/secrets/by-name/API_KEY?project_id=<id>&environment=prod" \
-H "Authorization: Bearer <machine-token>" | jq -r .value| ็นๆง | ๅฎ็ฐ |
|---|---|
| ๐ | AES-256-GCM - ่กไธๆ ๅๅ ๅฏ็ฎๆณ |
| ๐ง | PBKDF2 600K - OWASP ๆจ่่ฟญไปฃๆฌกๆฐ |
| โฐ | Token Rotation - ๆฏๆ่ชๅจ่ฝฎๆขๅๆค้ |
| ๐ก๏ธ | IP Whitelist - ้ๅถ่ฎฟ้ฎๆฅๆบ |
| ๐ | Time Window - ๅบไบๆถ้ด็่ฎฟ้ฎๆงๅถ |
| ๐ | Audit Trail - ๅฎๆด็่ฎฟ้ฎๆฅๅฟ |
| ๐ฆ | D1 Atomic Rate Limiting - ้ฒ็ซๆๆกไปถ้็้ๅถ |
| ๐ | Constant-Time Comparison - ้ฒๆถๅบๆปๅป |
| ๐ก๏ธ | Project Ownership Verification - ้ฒ่ทจ็จๆท่ฎฟ้ฎ |
ๆฌ้กน็ฎ็ป่ฟๅ จ้ขๅฎๅ จๅฎก่ฎก๏ผๅทฒไฟฎๅคไปฅไธ้ฎ้ข๏ผ
- โ ้็้ๅถ็ป่ฟ - ็งป้คไธๅฎๅ จ็ๅฏผๅ ฅ็ป่ฟ้ป่พ
- โ Cache API ็ซๆๆกไปถ - ๆน็จ D1 ๅๅญๆไฝ้ฒๆญขๅนถๅ็ป่ฟ
- โ ้กน็ฎๆๆๆ้ช่ฏ็ผบๅคฑ - ๆทปๅ ่ทจ็จๆท่ฎฟ้ฎ้ฒๆค
- โ ๅธธ้ๆถ้ดๆฏ่พๆถๅบๆณๆผ - ไฟฎๅค API Key ๆฏ่พๅฎ็ฐ
- โ SM ็ซฏ็น็ผบๅฐ้็้ๅถ - ไธบ Machine Account Token ๆทปๅ ้ๆต
- โ ๅญ่ฏ่ฎฟ้ฎๅฎก่ฎก็ฒๅบ - ่กฅๅ จ GET /api/secrets/:id ๅฎก่ฎกๆฅๅฟ
- โ ๅ ๅญๆบขๅบ้ฃ้ฉ - ๅๆญฅๅๅบๆทปๅ 50MB ๅคงๅฐ้ๅถ
- โ ็ผๅญๆ ็ๅข้ฟ - AuthService ๆทปๅ LRU ๆทๆฑฐ็ญ็ฅ
- โ ็ปๅฝ้ๅฎ่ฟไบๅฎฝๆพ - ไผๅไธบ 5ๆฌก/15ๅ้็ญ็ฅ
| ๆนๆณ | ็ซฏ็น | ๆ่ฟฐ |
|---|---|---|
POST |
/api/machine-accounts |
ๅๅปบๆบๅจ่ดฆๅท |
GET |
/api/machine-accounts |
ๅๅบๆๆๆบๅจ่ดฆๅท |
GET |
/api/machine-accounts/:id |
่ทๅๆบๅจ่ดฆๅท่ฏฆๆ |
PUT |
/api/machine-accounts/:id |
ๆดๆฐๆบๅจ่ดฆๅท |
DELETE |
/api/machine-accounts/:id |
ๅ ้คๆบๅจ่ดฆๅท |
POST |
/api/machine-accounts/:id/token |
็ๆ่ฎฟ้ฎไปค็ |
POST |
/api/machine-accounts/:id/revoke-token |
ๆค้่ฎฟ้ฎไปค็ |
| ๆนๆณ | ็ซฏ็น | ๆ่ฟฐ |
|---|---|---|
POST |
/api/projects |
ๅๅปบ้กน็ฎ |
GET |
/api/projects |
ๅๅบๆๆ้กน็ฎ |
GET |
/api/projects/:id |
่ทๅ้กน็ฎ่ฏฆๆ |
DELETE |
/api/projects/:id |
ๅ ้ค้กน็ฎ |
| ๆนๆณ | ็ซฏ็น | ๆ่ฟฐ |
|---|---|---|
POST |
/api/secrets |
ๅๅปบๅญ่ฏ |
GET |
/api/secrets?project_id=<id> |
ๅๅบ้กน็ฎไธ็ๅญ่ฏ |
GET |
/api/secrets/:id |
่ทๅๅญ่ฏ่ฏฆๆ |
PUT |
/api/secrets/:id |
ๆดๆฐๅญ่ฏ |
DELETE |
/api/secrets/:id |
ๅ ้คๅญ่ฏ |
GET |
/api/secrets/by-name/:name |
้่ฟๅ็งฐ่ทๅๅญ่ฏ |
ๆไปฌๆไพๅค่ฏญ่จ SDK๏ผ็ฎๅ Agent ้ๆ๏ผ
from tirisfal import TirisfalClient
client = TirisfalClient(
server="https://your-worker.workers.dev",
token="your-machine-account-token"
)
secret = client.get_secret("API_KEY", project_id="xxx", environment="prod")
print(secret.value)const { TirisfalClient } = require('@tirisfal/sdk');
const client = new TirisfalClient({
server: 'https://your-worker.workers.dev',
token: 'your-machine-account-token'
});
const secret = await client.getSecret('API_KEY', { projectId: 'xxx' });
console.log(secret.value);import "github.com/ialer/tirisfal/sdk/go"
client := tirisfal.NewClient("https://your-worker.workers.dev", "your-token")
secret, _ := client.GetSecret("API_KEY", "project-id", "prod")
fmt.Println(secret.Value)โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Cloudflare Workers โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ Auth โ โ SM API โ โ Backup โ โ
โ โ Service โ โ Service โ โ Service โ โ
โ โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ โโโโโโโโฌโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโดโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโดโโโโโโโ โ
โ โ SecretsManagerService โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ AES-256-GCM Encryption โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ D1 Database โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ โ
โ โ โ secrets โ โ projects โ โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| ๅ้ | ๅฟ ๅกซ | ๆ่ฟฐ |
|---|---|---|
JWT_SECRET |
โ | JWT ็ญพๅๅฏ้ฅ๏ผ32+ ๅญ็ฌฆ๏ผ |
ENCRYPTION_KEY |
โ | ๅ ๅฏๅฏ้ฅ๏ผ32+ ๅญ็ฌฆ๏ผ |
DB |
โ | D1 ๆฐๆฎๅบ็ปๅฎ |
ATTACHMENTS |
โ | R2 ๅญๅจๆกถ๏ผๅฏ้๏ผ |
# ็ๆ JWT ๅฏ้ฅ
openssl rand -hex 32
# ็ๆๅ ๅฏๅฏ้ฅ
openssl rand -base64 32้กน็ฎไฝฟ็จไปฅไธ D1 ๆฐๆฎ่กจ๏ผ
| ่กจๅ | ็จ้ |
|---|---|
users |
็จๆท่ดฆๆท |
ciphers |
ๅฏ็ ้กน |
folders |
ๆไปถๅคน |
attachments |
้ไปถ |
sends |
Send ๅไบซ |
refresh_tokens |
ๅทๆฐไปค็ |
devices |
่ฎพๅค็ปๅฎ |
audit_logs |
ๅฎก่ฎกๆฅๅฟ |
login_attempts_ip |
็ปๅฝๅคฑ่ดฅ่ฎฐๅฝ |
rate_limits |
API ้็้ๅถ |
machine_accounts |
ๆบๅจ่ดฆๅท |
sm_projects |
้กน็ฎ |
secrets |
ๅญ่ฏ |
machine_account_projects |
ๆบๅจ่ดฆๅท้กน็ฎๆ้ |
secret_access_logs |
ๅญ่ฏ่ฎฟ้ฎๆฅๅฟ |
ๆฌข่ฟ่ดก็ฎ๏ผ่ฏท้ ่ฏป CONTRIBUTING.md ไบ่งฃ่ฏฆๆ ใ
ๆฌ้กน็ฎไฝฟ็จ LGPL-3.0 ่ฎธๅฏ่ฏใ
Built with โค๏ธ by SN Team