code-abyss 1.6.16 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/bin/install.js +59 -163
- package/bin/lib/ccline.js +82 -0
- package/bin/lib/utils.js +61 -0
- package/package.json +5 -2
- package/skills/SKILL.md +24 -16
- package/skills/domains/ai/SKILL.md +2 -2
- package/skills/domains/ai/prompt-and-eval.md +279 -0
- package/skills/domains/architecture/SKILL.md +2 -3
- package/skills/domains/architecture/security-arch.md +87 -0
- package/skills/domains/data-engineering/SKILL.md +188 -26
- package/skills/domains/development/SKILL.md +1 -4
- package/skills/domains/devops/SKILL.md +3 -5
- package/skills/domains/devops/performance.md +63 -0
- package/skills/domains/devops/testing.md +97 -0
- package/skills/domains/frontend-design/SKILL.md +12 -3
- package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
- package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
- package/skills/domains/frontend-design/engineering.md +287 -0
- package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
- package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
- package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
- package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
- package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
- package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
- package/skills/domains/infrastructure/SKILL.md +174 -34
- package/skills/domains/mobile/SKILL.md +211 -21
- package/skills/domains/orchestration/SKILL.md +1 -0
- package/skills/domains/security/SKILL.md +4 -6
- package/skills/domains/security/blue-team.md +57 -0
- package/skills/domains/security/red-team.md +54 -0
- package/skills/domains/security/threat-intel.md +50 -0
- package/skills/orchestration/multi-agent/SKILL.md +195 -46
- package/skills/run_skill.js +139 -0
- package/skills/tools/gen-docs/SKILL.md +6 -4
- package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
- package/skills/tools/lib/shared.js +98 -0
- package/skills/tools/verify-change/SKILL.md +8 -6
- package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
- package/skills/tools/verify-module/SKILL.md +6 -4
- package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
- package/skills/tools/verify-quality/SKILL.md +5 -3
- package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
- package/skills/tools/verify-security/SKILL.md +7 -5
- package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
- package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
- package/skills/domains/COVERAGE_PLAN.md +0 -232
- package/skills/domains/ai/model-evaluation.md +0 -790
- package/skills/domains/ai/prompt-engineering.md +0 -703
- package/skills/domains/architecture/compliance.md +0 -299
- package/skills/domains/architecture/data-security.md +0 -184
- package/skills/domains/data-engineering/data-pipeline.md +0 -762
- package/skills/domains/data-engineering/data-quality.md +0 -894
- package/skills/domains/data-engineering/stream-processing.md +0 -791
- package/skills/domains/development/dart.md +0 -963
- package/skills/domains/development/kotlin.md +0 -834
- package/skills/domains/development/php.md +0 -659
- package/skills/domains/development/swift.md +0 -755
- package/skills/domains/devops/e2e-testing.md +0 -914
- package/skills/domains/devops/performance-testing.md +0 -734
- package/skills/domains/devops/testing-strategy.md +0 -667
- package/skills/domains/frontend-design/build-tools.md +0 -743
- package/skills/domains/frontend-design/performance.md +0 -734
- package/skills/domains/frontend-design/testing.md +0 -699
- package/skills/domains/infrastructure/gitops.md +0 -735
- package/skills/domains/infrastructure/iac.md +0 -855
- package/skills/domains/infrastructure/kubernetes.md +0 -1018
- package/skills/domains/mobile/android-dev.md +0 -979
- package/skills/domains/mobile/cross-platform.md +0 -795
- package/skills/domains/mobile/ios-dev.md +0 -931
- package/skills/domains/security/secrets-management.md +0 -834
- package/skills/domains/security/supply-chain.md +0 -931
- package/skills/domains/security/threat-modeling.md +0 -828
- package/skills/run_skill.py +0 -153
- package/skills/tests/README.md +0 -225
- package/skills/tests/SUMMARY.md +0 -362
- package/skills/tests/__init__.py +0 -3
- package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
- package/skills/tests/test_change_analyzer.py +0 -558
- package/skills/tests/test_doc_generator.py +0 -538
- package/skills/tests/test_module_scanner.py +0 -376
- package/skills/tests/test_quality_checker.py +0 -516
- package/skills/tests/test_security_scanner.py +0 -426
- package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
- package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
- package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
- package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
- package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
- package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
- package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
- package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
|
@@ -1,834 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: secrets-management
|
|
3
|
-
description: 密钥管理与加密。HashiCorp Vault、AWS KMS、密钥轮转、加密最佳实践、密钥生命周期。当用户提到密钥管理、Vault、KMS、密钥轮转、加密、密钥存储、凭证管理时使用。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 🔐 密钥管理 · Secrets Management
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 密钥生命周期
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
生成 → 存储 → 分发 → 使用 → 轮转 → 撤销 → 销毁
|
|
13
|
-
│ │ │ │ │ │ │
|
|
14
|
-
└─ 强度 ─┴─ 加密 ─┴─ 授权 ─┴─ 审计 ─┴─ 自动 ─┴─ 即时 ─┴─ 安全
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## HashiCorp Vault
|
|
18
|
-
|
|
19
|
-
### Vault 架构
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
┌─────────────────────────────────────────┐
|
|
23
|
-
│ Vault API │
|
|
24
|
-
├─────────────────────────────────────────┤
|
|
25
|
-
│ Auth Methods │ Secrets Engines │
|
|
26
|
-
│ - Token │ - KV (Key/Value) │
|
|
27
|
-
│ - LDAP │ - Database │
|
|
28
|
-
│ - Kubernetes │ - AWS │
|
|
29
|
-
│ - AppRole │ - PKI │
|
|
30
|
-
├─────────────────────────────────────────┤
|
|
31
|
-
│ Storage Backend │
|
|
32
|
-
│ - Consul / etcd / S3 / File │
|
|
33
|
-
└─────────────────────────────────────────┘
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Vault 部署
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
# 安装 Vault
|
|
40
|
-
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
|
|
41
|
-
unzip vault_1.15.0_linux_amd64.zip
|
|
42
|
-
sudo mv vault /usr/local/bin/
|
|
43
|
-
|
|
44
|
-
# 启动开发服务器
|
|
45
|
-
vault server -dev
|
|
46
|
-
|
|
47
|
-
# 生产配置
|
|
48
|
-
cat > vault-config.hcl <<EOF
|
|
49
|
-
storage "consul" {
|
|
50
|
-
address = "127.0.0.1:8500"
|
|
51
|
-
path = "vault/"
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
listener "tcp" {
|
|
55
|
-
address = "0.0.0.0:8200"
|
|
56
|
-
tls_cert_file = "/etc/vault/tls/vault.crt"
|
|
57
|
-
tls_key_file = "/etc/vault/tls/vault.key"
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
api_addr = "https://vault.example.com:8200"
|
|
61
|
-
cluster_addr = "https://vault.example.com:8201"
|
|
62
|
-
ui = true
|
|
63
|
-
EOF
|
|
64
|
-
|
|
65
|
-
# 启动 Vault
|
|
66
|
-
vault server -config=vault-config.hcl
|
|
67
|
-
|
|
68
|
-
# 初始化
|
|
69
|
-
vault operator init -key-shares=5 -key-threshold=3
|
|
70
|
-
|
|
71
|
-
# 解封
|
|
72
|
-
vault operator unseal <unseal-key-1>
|
|
73
|
-
vault operator unseal <unseal-key-2>
|
|
74
|
-
vault operator unseal <unseal-key-3>
|
|
75
|
-
|
|
76
|
-
# 登录
|
|
77
|
-
vault login <root-token>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### KV Secrets Engine
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
# 启用 KV v2
|
|
84
|
-
vault secrets enable -path=secret kv-v2
|
|
85
|
-
|
|
86
|
-
# 写入密钥
|
|
87
|
-
vault kv put secret/myapp/config \
|
|
88
|
-
db_password="supersecret" \
|
|
89
|
-
api_key="abc123"
|
|
90
|
-
|
|
91
|
-
# 读取密钥
|
|
92
|
-
vault kv get secret/myapp/config
|
|
93
|
-
vault kv get -field=db_password secret/myapp/config
|
|
94
|
-
|
|
95
|
-
# 版本管理
|
|
96
|
-
vault kv put secret/myapp/config db_password="newsecret"
|
|
97
|
-
vault kv get -version=1 secret/myapp/config
|
|
98
|
-
|
|
99
|
-
# 删除版本
|
|
100
|
-
vault kv delete -versions=2 secret/myapp/config
|
|
101
|
-
|
|
102
|
-
# 永久删除
|
|
103
|
-
vault kv destroy -versions=1,2 secret/myapp/config
|
|
104
|
-
|
|
105
|
-
# 恢复删除
|
|
106
|
-
vault kv undelete -versions=2 secret/myapp/config
|
|
107
|
-
|
|
108
|
-
# 元数据
|
|
109
|
-
vault kv metadata get secret/myapp/config
|
|
110
|
-
vault kv metadata put -max-versions=5 secret/myapp/config
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### 动态密钥 (Database)
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
# 启用数据库引擎
|
|
117
|
-
vault secrets enable database
|
|
118
|
-
|
|
119
|
-
# 配置数据库连接
|
|
120
|
-
vault write database/config/postgresql \
|
|
121
|
-
plugin_name=postgresql-database-plugin \
|
|
122
|
-
allowed_roles="readonly,readwrite" \
|
|
123
|
-
connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb" \
|
|
124
|
-
username="vault" \
|
|
125
|
-
password="vaultpass"
|
|
126
|
-
|
|
127
|
-
# 创建角色
|
|
128
|
-
vault write database/roles/readonly \
|
|
129
|
-
db_name=postgresql \
|
|
130
|
-
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
|
|
131
|
-
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
|
132
|
-
default_ttl="1h" \
|
|
133
|
-
max_ttl="24h"
|
|
134
|
-
|
|
135
|
-
# 生成动态凭证
|
|
136
|
-
vault read database/creds/readonly
|
|
137
|
-
|
|
138
|
-
# 输出示例:
|
|
139
|
-
# Key Value
|
|
140
|
-
# --- -----
|
|
141
|
-
# lease_id database/creds/readonly/abc123
|
|
142
|
-
# lease_duration 1h
|
|
143
|
-
# username v-root-readonly-xyz789
|
|
144
|
-
# password A1b2C3d4E5f6
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### AppRole 认证
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
# 启用 AppRole
|
|
151
|
-
vault auth enable approle
|
|
152
|
-
|
|
153
|
-
# 创建策略
|
|
154
|
-
vault policy write myapp-policy - <<EOF
|
|
155
|
-
path "secret/data/myapp/*" {
|
|
156
|
-
capabilities = ["read"]
|
|
157
|
-
}
|
|
158
|
-
path "database/creds/readonly" {
|
|
159
|
-
capabilities = ["read"]
|
|
160
|
-
}
|
|
161
|
-
EOF
|
|
162
|
-
|
|
163
|
-
# 创建 AppRole
|
|
164
|
-
vault write auth/approle/role/myapp \
|
|
165
|
-
token_policies="myapp-policy" \
|
|
166
|
-
token_ttl=1h \
|
|
167
|
-
token_max_ttl=4h
|
|
168
|
-
|
|
169
|
-
# 获取 Role ID
|
|
170
|
-
vault read auth/approle/role/myapp/role-id
|
|
171
|
-
|
|
172
|
-
# 生成 Secret ID
|
|
173
|
-
vault write -f auth/approle/role/myapp/secret-id
|
|
174
|
-
|
|
175
|
-
# 使用 AppRole 登录
|
|
176
|
-
vault write auth/approle/login \
|
|
177
|
-
role_id="<role-id>" \
|
|
178
|
-
secret_id="<secret-id>"
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Vault Python SDK
|
|
182
|
-
|
|
183
|
-
```python
|
|
184
|
-
#!/usr/bin/env python3
|
|
185
|
-
"""Vault 客户端封装"""
|
|
186
|
-
import hvac
|
|
187
|
-
from typing import Dict, Optional
|
|
188
|
-
|
|
189
|
-
class VaultClient:
|
|
190
|
-
def __init__(self, url: str, token: Optional[str] = None):
|
|
191
|
-
self.client = hvac.Client(url=url, token=token)
|
|
192
|
-
|
|
193
|
-
def login_approle(self, role_id: str, secret_id: str):
|
|
194
|
-
"""AppRole 登录"""
|
|
195
|
-
response = self.client.auth.approle.login(
|
|
196
|
-
role_id=role_id,
|
|
197
|
-
secret_id=secret_id
|
|
198
|
-
)
|
|
199
|
-
self.client.token = response['auth']['client_token']
|
|
200
|
-
|
|
201
|
-
def read_secret(self, path: str) -> Dict:
|
|
202
|
-
"""读取 KV 密钥"""
|
|
203
|
-
response = self.client.secrets.kv.v2.read_secret_version(
|
|
204
|
-
path=path,
|
|
205
|
-
mount_point='secret'
|
|
206
|
-
)
|
|
207
|
-
return response['data']['data']
|
|
208
|
-
|
|
209
|
-
def write_secret(self, path: str, data: Dict):
|
|
210
|
-
"""写入 KV 密钥"""
|
|
211
|
-
self.client.secrets.kv.v2.create_or_update_secret(
|
|
212
|
-
path=path,
|
|
213
|
-
secret=data,
|
|
214
|
-
mount_point='secret'
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
def get_db_creds(self, role: str) -> Dict:
|
|
218
|
-
"""获取动态数据库凭证"""
|
|
219
|
-
response = self.client.secrets.database.generate_credentials(
|
|
220
|
-
name=role
|
|
221
|
-
)
|
|
222
|
-
return {
|
|
223
|
-
'username': response['data']['username'],
|
|
224
|
-
'password': response['data']['password'],
|
|
225
|
-
'lease_id': response['lease_id'],
|
|
226
|
-
'lease_duration': response['lease_duration']
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
def renew_lease(self, lease_id: str, increment: int = 3600):
|
|
230
|
-
"""续租"""
|
|
231
|
-
self.client.sys.renew_lease(
|
|
232
|
-
lease_id=lease_id,
|
|
233
|
-
increment=increment
|
|
234
|
-
)
|
|
235
|
-
|
|
236
|
-
def revoke_lease(self, lease_id: str):
|
|
237
|
-
"""撤销租约"""
|
|
238
|
-
self.client.sys.revoke_lease(lease_id)
|
|
239
|
-
|
|
240
|
-
# 使用示例
|
|
241
|
-
vault = VaultClient('https://vault.example.com:8200')
|
|
242
|
-
vault.login_approle(role_id='xxx', secret_id='yyy')
|
|
243
|
-
|
|
244
|
-
# 读取静态密钥
|
|
245
|
-
config = vault.read_secret('myapp/config')
|
|
246
|
-
print(f"DB Password: {config['db_password']}")
|
|
247
|
-
|
|
248
|
-
# 获取动态凭证
|
|
249
|
-
creds = vault.get_db_creds('readonly')
|
|
250
|
-
print(f"Username: {creds['username']}, Password: {creds['password']}")
|
|
251
|
-
|
|
252
|
-
# 续租
|
|
253
|
-
vault.renew_lease(creds['lease_id'], increment=7200)
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
## AWS KMS
|
|
257
|
-
|
|
258
|
-
### KMS 密钥管理
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
# 创建 KMS 密钥
|
|
262
|
-
aws kms create-key \
|
|
263
|
-
--description "Application encryption key" \
|
|
264
|
-
--key-usage ENCRYPT_DECRYPT \
|
|
265
|
-
--origin AWS_KMS
|
|
266
|
-
|
|
267
|
-
# 创建别名
|
|
268
|
-
aws kms create-alias \
|
|
269
|
-
--alias-name alias/myapp \
|
|
270
|
-
--target-key-id <key-id>
|
|
271
|
-
|
|
272
|
-
# 加密数据
|
|
273
|
-
aws kms encrypt \
|
|
274
|
-
--key-id alias/myapp \
|
|
275
|
-
--plaintext "sensitive data" \
|
|
276
|
-
--output text \
|
|
277
|
-
--query CiphertextBlob
|
|
278
|
-
|
|
279
|
-
# 解密数据
|
|
280
|
-
aws kms decrypt \
|
|
281
|
-
--ciphertext-blob fileb://encrypted.bin \
|
|
282
|
-
--output text \
|
|
283
|
-
--query Plaintext | base64 --decode
|
|
284
|
-
|
|
285
|
-
# 生成数据密钥
|
|
286
|
-
aws kms generate-data-key \
|
|
287
|
-
--key-id alias/myapp \
|
|
288
|
-
--key-spec AES_256
|
|
289
|
-
|
|
290
|
-
# 轮转密钥
|
|
291
|
-
aws kms enable-key-rotation --key-id <key-id>
|
|
292
|
-
|
|
293
|
-
# 查看轮转状态
|
|
294
|
-
aws kms get-key-rotation-status --key-id <key-id>
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### KMS 信封加密
|
|
298
|
-
|
|
299
|
-
```python
|
|
300
|
-
#!/usr/bin/env python3
|
|
301
|
-
"""KMS 信封加密实现"""
|
|
302
|
-
import boto3
|
|
303
|
-
import base64
|
|
304
|
-
from cryptography.fernet import Fernet
|
|
305
|
-
from typing import Tuple
|
|
306
|
-
|
|
307
|
-
class KMSEnvelopeEncryption:
|
|
308
|
-
def __init__(self, kms_key_id: str):
|
|
309
|
-
self.kms = boto3.client('kms')
|
|
310
|
-
self.kms_key_id = kms_key_id
|
|
311
|
-
|
|
312
|
-
def encrypt(self, plaintext: bytes) -> Tuple[bytes, bytes]:
|
|
313
|
-
"""信封加密"""
|
|
314
|
-
# 1. 生成数据密钥
|
|
315
|
-
response = self.kms.generate_data_key(
|
|
316
|
-
KeyId=self.kms_key_id,
|
|
317
|
-
KeySpec='AES_256'
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
plaintext_key = response['Plaintext']
|
|
321
|
-
encrypted_key = response['CiphertextBlob']
|
|
322
|
-
|
|
323
|
-
# 2. 使用数据密钥加密数据
|
|
324
|
-
fernet = Fernet(base64.urlsafe_b64encode(plaintext_key[:32]))
|
|
325
|
-
encrypted_data = fernet.encrypt(plaintext)
|
|
326
|
-
|
|
327
|
-
# 3. 返回加密的数据和加密的密钥
|
|
328
|
-
return encrypted_data, encrypted_key
|
|
329
|
-
|
|
330
|
-
def decrypt(self, encrypted_data: bytes, encrypted_key: bytes) -> bytes:
|
|
331
|
-
"""信封解密"""
|
|
332
|
-
# 1. 解密数据密钥
|
|
333
|
-
response = self.kms.decrypt(CiphertextBlob=encrypted_key)
|
|
334
|
-
plaintext_key = response['Plaintext']
|
|
335
|
-
|
|
336
|
-
# 2. 使用数据密钥解密数据
|
|
337
|
-
fernet = Fernet(base64.urlsafe_b64encode(plaintext_key[:32]))
|
|
338
|
-
plaintext = fernet.decrypt(encrypted_data)
|
|
339
|
-
|
|
340
|
-
return plaintext
|
|
341
|
-
|
|
342
|
-
# 使用示例
|
|
343
|
-
kms = KMSEnvelopeEncryption('arn:aws:kms:us-east-1:123456789012:key/xxx')
|
|
344
|
-
|
|
345
|
-
# 加密
|
|
346
|
-
data = b"Sensitive information"
|
|
347
|
-
encrypted_data, encrypted_key = kms.encrypt(data)
|
|
348
|
-
|
|
349
|
-
# 解密
|
|
350
|
-
decrypted_data = kms.decrypt(encrypted_data, encrypted_key)
|
|
351
|
-
print(decrypted_data.decode())
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### AWS Secrets Manager
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
# 创建密钥
|
|
358
|
-
aws secretsmanager create-secret \
|
|
359
|
-
--name myapp/db/password \
|
|
360
|
-
--secret-string '{"username":"admin","password":"supersecret"}'
|
|
361
|
-
|
|
362
|
-
# 读取密钥
|
|
363
|
-
aws secretsmanager get-secret-value \
|
|
364
|
-
--secret-id myapp/db/password \
|
|
365
|
-
--query SecretString \
|
|
366
|
-
--output text
|
|
367
|
-
|
|
368
|
-
# 更新密钥
|
|
369
|
-
aws secretsmanager update-secret \
|
|
370
|
-
--secret-id myapp/db/password \
|
|
371
|
-
--secret-string '{"username":"admin","password":"newsecret"}'
|
|
372
|
-
|
|
373
|
-
# 轮转密钥
|
|
374
|
-
aws secretsmanager rotate-secret \
|
|
375
|
-
--secret-id myapp/db/password \
|
|
376
|
-
--rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:rotate
|
|
377
|
-
|
|
378
|
-
# 配置自动轮转
|
|
379
|
-
aws secretsmanager rotate-secret \
|
|
380
|
-
--secret-id myapp/db/password \
|
|
381
|
-
--rotation-rules AutomaticallyAfterDays=30
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### Secrets Manager Python
|
|
385
|
-
|
|
386
|
-
```python
|
|
387
|
-
#!/usr/bin/env python3
|
|
388
|
-
"""AWS Secrets Manager 客户端"""
|
|
389
|
-
import boto3
|
|
390
|
-
import json
|
|
391
|
-
from typing import Dict
|
|
392
|
-
|
|
393
|
-
class SecretsManager:
|
|
394
|
-
def __init__(self, region: str = 'us-east-1'):
|
|
395
|
-
self.client = boto3.client('secretsmanager', region_name=region)
|
|
396
|
-
|
|
397
|
-
def get_secret(self, secret_id: str) -> Dict:
|
|
398
|
-
"""获取密钥"""
|
|
399
|
-
response = self.client.get_secret_value(SecretId=secret_id)
|
|
400
|
-
return json.loads(response['SecretString'])
|
|
401
|
-
|
|
402
|
-
def create_secret(self, name: str, secret: Dict):
|
|
403
|
-
"""创建密钥"""
|
|
404
|
-
self.client.create_secret(
|
|
405
|
-
Name=name,
|
|
406
|
-
SecretString=json.dumps(secret)
|
|
407
|
-
)
|
|
408
|
-
|
|
409
|
-
def update_secret(self, secret_id: str, secret: Dict):
|
|
410
|
-
"""更新密钥"""
|
|
411
|
-
self.client.update_secret(
|
|
412
|
-
SecretId=secret_id,
|
|
413
|
-
SecretString=json.dumps(secret)
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
def rotate_secret(self, secret_id: str, lambda_arn: str):
|
|
417
|
-
"""轮转密钥"""
|
|
418
|
-
self.client.rotate_secret(
|
|
419
|
-
SecretId=secret_id,
|
|
420
|
-
RotationLambdaARN=lambda_arn,
|
|
421
|
-
RotationRules={'AutomaticallyAfterDays': 30}
|
|
422
|
-
)
|
|
423
|
-
|
|
424
|
-
# 使用示例
|
|
425
|
-
sm = SecretsManager()
|
|
426
|
-
db_creds = sm.get_secret('myapp/db/password')
|
|
427
|
-
print(f"Username: {db_creds['username']}")
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
## 密钥轮转策略
|
|
431
|
-
|
|
432
|
-
### 自动轮转实现
|
|
433
|
-
|
|
434
|
-
```python
|
|
435
|
-
#!/usr/bin/env python3
|
|
436
|
-
"""密钥自动轮转"""
|
|
437
|
-
import hashlib
|
|
438
|
-
import secrets
|
|
439
|
-
from datetime import datetime, timedelta
|
|
440
|
-
from typing import Dict, Optional
|
|
441
|
-
|
|
442
|
-
class SecretRotation:
|
|
443
|
-
def __init__(self, vault_client):
|
|
444
|
-
self.vault = vault_client
|
|
445
|
-
self.rotation_period = timedelta(days=90)
|
|
446
|
-
|
|
447
|
-
def generate_password(self, length: int = 32) -> str:
|
|
448
|
-
"""生成强密码"""
|
|
449
|
-
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()"
|
|
450
|
-
return ''.join(secrets.choice(alphabet) for _ in range(length))
|
|
451
|
-
|
|
452
|
-
def should_rotate(self, secret_path: str) -> bool:
|
|
453
|
-
"""检查是否需要轮转"""
|
|
454
|
-
metadata = self.vault.client.secrets.kv.v2.read_secret_metadata(
|
|
455
|
-
path=secret_path,
|
|
456
|
-
mount_point='secret'
|
|
457
|
-
)
|
|
458
|
-
|
|
459
|
-
created_time = datetime.fromisoformat(
|
|
460
|
-
metadata['data']['created_time'].replace('Z', '+00:00')
|
|
461
|
-
)
|
|
462
|
-
|
|
463
|
-
return datetime.now() - created_time > self.rotation_period
|
|
464
|
-
|
|
465
|
-
def rotate_database_password(self, db_config: Dict):
|
|
466
|
-
"""轮转数据库密码"""
|
|
467
|
-
# 1. 生成新密码
|
|
468
|
-
new_password = self.generate_password()
|
|
469
|
-
|
|
470
|
-
# 2. 在数据库中更新密码
|
|
471
|
-
import psycopg2
|
|
472
|
-
conn = psycopg2.connect(**db_config)
|
|
473
|
-
cursor = conn.cursor()
|
|
474
|
-
cursor.execute(
|
|
475
|
-
f"ALTER USER {db_config['user']} WITH PASSWORD %s",
|
|
476
|
-
(new_password,)
|
|
477
|
-
)
|
|
478
|
-
conn.commit()
|
|
479
|
-
conn.close()
|
|
480
|
-
|
|
481
|
-
# 3. 更新 Vault 中的密钥
|
|
482
|
-
self.vault.write_secret(
|
|
483
|
-
'myapp/db/password',
|
|
484
|
-
{'password': new_password}
|
|
485
|
-
)
|
|
486
|
-
|
|
487
|
-
# 4. 记录轮转事件
|
|
488
|
-
self.log_rotation('database', 'myapp/db/password')
|
|
489
|
-
|
|
490
|
-
def rotate_api_key(self, service: str, api_endpoint: str):
|
|
491
|
-
"""轮转 API 密钥"""
|
|
492
|
-
# 1. 调用服务 API 生成新密钥
|
|
493
|
-
import requests
|
|
494
|
-
response = requests.post(
|
|
495
|
-
f"{api_endpoint}/keys/rotate",
|
|
496
|
-
headers={'Authorization': f'Bearer {self.get_current_key(service)}'}
|
|
497
|
-
)
|
|
498
|
-
new_key = response.json()['api_key']
|
|
499
|
-
|
|
500
|
-
# 2. 更新 Vault
|
|
501
|
-
self.vault.write_secret(
|
|
502
|
-
f'{service}/api_key',
|
|
503
|
-
{'key': new_key}
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
# 3. 撤销旧密钥(延迟撤销,给应用时间更新)
|
|
507
|
-
# 在 24 小时后撤销
|
|
508
|
-
|
|
509
|
-
def log_rotation(self, secret_type: str, path: str):
|
|
510
|
-
"""记录轮转日志"""
|
|
511
|
-
log_entry = {
|
|
512
|
-
'timestamp': datetime.now().isoformat(),
|
|
513
|
-
'type': secret_type,
|
|
514
|
-
'path': path,
|
|
515
|
-
'action': 'rotated'
|
|
516
|
-
}
|
|
517
|
-
print(f"[ROTATION] {log_entry}")
|
|
518
|
-
|
|
519
|
-
def get_current_key(self, service: str) -> str:
|
|
520
|
-
"""获取当前密钥"""
|
|
521
|
-
secret = self.vault.read_secret(f'{service}/api_key')
|
|
522
|
-
return secret['key']
|
|
523
|
-
|
|
524
|
-
# 使用示例
|
|
525
|
-
from vault_client import VaultClient
|
|
526
|
-
|
|
527
|
-
vault = VaultClient('https://vault.example.com:8200')
|
|
528
|
-
vault.login_approle(role_id='xxx', secret_id='yyy')
|
|
529
|
-
|
|
530
|
-
rotation = SecretRotation(vault)
|
|
531
|
-
|
|
532
|
-
# 检查并轮转
|
|
533
|
-
if rotation.should_rotate('myapp/db/password'):
|
|
534
|
-
rotation.rotate_database_password({
|
|
535
|
-
'host': 'localhost',
|
|
536
|
-
'database': 'mydb',
|
|
537
|
-
'user': 'myapp',
|
|
538
|
-
'password': vault.read_secret('myapp/db/password')['password']
|
|
539
|
-
})
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### 轮转策略配置
|
|
543
|
-
|
|
544
|
-
```yaml
|
|
545
|
-
# rotation-policy.yaml
|
|
546
|
-
rotation_policies:
|
|
547
|
-
- name: "database_passwords"
|
|
548
|
-
type: "database"
|
|
549
|
-
schedule: "0 2 * * 0" # 每周日凌晨2点
|
|
550
|
-
max_age_days: 90
|
|
551
|
-
notification:
|
|
552
|
-
- email: security@company.com
|
|
553
|
-
- slack: "#security-alerts"
|
|
554
|
-
|
|
555
|
-
- name: "api_keys"
|
|
556
|
-
type: "api"
|
|
557
|
-
schedule: "0 3 1 * *" # 每月1号凌晨3点
|
|
558
|
-
max_age_days: 30
|
|
559
|
-
grace_period_hours: 24
|
|
560
|
-
|
|
561
|
-
- name: "tls_certificates"
|
|
562
|
-
type: "certificate"
|
|
563
|
-
schedule: "0 4 * * *" # 每天凌晨4点检查
|
|
564
|
-
renew_before_days: 30
|
|
565
|
-
auto_deploy: true
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
## 加密最佳实践
|
|
569
|
-
|
|
570
|
-
### 静态加密
|
|
571
|
-
|
|
572
|
-
```python
|
|
573
|
-
#!/usr/bin/env python3
|
|
574
|
-
"""数据静态加密"""
|
|
575
|
-
from cryptography.fernet import Fernet
|
|
576
|
-
from cryptography.hazmat.primitives import hashes
|
|
577
|
-
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2
|
|
578
|
-
import base64
|
|
579
|
-
import os
|
|
580
|
-
|
|
581
|
-
class DataEncryption:
|
|
582
|
-
def __init__(self, master_key: bytes):
|
|
583
|
-
self.master_key = master_key
|
|
584
|
-
|
|
585
|
-
def derive_key(self, salt: bytes) -> bytes:
|
|
586
|
-
"""从主密钥派生加密密钥"""
|
|
587
|
-
kdf = PBKDF2(
|
|
588
|
-
algorithm=hashes.SHA256(),
|
|
589
|
-
length=32,
|
|
590
|
-
salt=salt,
|
|
591
|
-
iterations=100000,
|
|
592
|
-
)
|
|
593
|
-
return base64.urlsafe_b64encode(kdf.derive(self.master_key))
|
|
594
|
-
|
|
595
|
-
def encrypt_field(self, plaintext: str, context: str = "") -> str:
|
|
596
|
-
"""加密字段"""
|
|
597
|
-
salt = os.urandom(16)
|
|
598
|
-
key = self.derive_key(salt + context.encode())
|
|
599
|
-
fernet = Fernet(key)
|
|
600
|
-
|
|
601
|
-
encrypted = fernet.encrypt(plaintext.encode())
|
|
602
|
-
# 返回: salt + encrypted_data
|
|
603
|
-
return base64.b64encode(salt + encrypted).decode()
|
|
604
|
-
|
|
605
|
-
def decrypt_field(self, ciphertext: str, context: str = "") -> str:
|
|
606
|
-
"""解密字段"""
|
|
607
|
-
data = base64.b64decode(ciphertext)
|
|
608
|
-
salt = data[:16]
|
|
609
|
-
encrypted = data[16:]
|
|
610
|
-
|
|
611
|
-
key = self.derive_key(salt + context.encode())
|
|
612
|
-
fernet = Fernet(key)
|
|
613
|
-
|
|
614
|
-
return fernet.decrypt(encrypted).decode()
|
|
615
|
-
|
|
616
|
-
# 使用示例
|
|
617
|
-
master_key = os.environ['MASTER_KEY'].encode()
|
|
618
|
-
crypto = DataEncryption(master_key)
|
|
619
|
-
|
|
620
|
-
# 加密敏感字段
|
|
621
|
-
encrypted_ssn = crypto.encrypt_field("123-45-6789", context="user:ssn")
|
|
622
|
-
encrypted_cc = crypto.encrypt_field("4111111111111111", context="user:cc")
|
|
623
|
-
|
|
624
|
-
# 解密
|
|
625
|
-
ssn = crypto.decrypt_field(encrypted_ssn, context="user:ssn")
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
### 传输加密
|
|
629
|
-
|
|
630
|
-
```python
|
|
631
|
-
#!/usr/bin/env python3
|
|
632
|
-
"""TLS 配置最佳实践"""
|
|
633
|
-
import ssl
|
|
634
|
-
import socket
|
|
635
|
-
|
|
636
|
-
def create_secure_context() -> ssl.SSLContext:
|
|
637
|
-
"""创建安全的 SSL 上下文"""
|
|
638
|
-
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
|
639
|
-
|
|
640
|
-
# 加载证书
|
|
641
|
-
context.load_cert_chain('server.crt', 'server.key')
|
|
642
|
-
|
|
643
|
-
# 仅允许 TLS 1.2+
|
|
644
|
-
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
|
645
|
-
|
|
646
|
-
# 禁用不安全的密码套件
|
|
647
|
-
context.set_ciphers('ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!MD5:!DSS')
|
|
648
|
-
|
|
649
|
-
# 启用 OCSP Stapling
|
|
650
|
-
context.options |= ssl.OP_NO_COMPRESSION
|
|
651
|
-
|
|
652
|
-
return context
|
|
653
|
-
|
|
654
|
-
# HTTPS 服务器示例
|
|
655
|
-
def run_https_server():
|
|
656
|
-
context = create_secure_context()
|
|
657
|
-
|
|
658
|
-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
|
659
|
-
sock.bind(('0.0.0.0', 8443))
|
|
660
|
-
sock.listen(5)
|
|
661
|
-
|
|
662
|
-
with context.wrap_socket(sock, server_side=True) as ssock:
|
|
663
|
-
while True:
|
|
664
|
-
conn, addr = ssock.accept()
|
|
665
|
-
# 处理连接
|
|
666
|
-
conn.close()
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
### 使用中加密 (Homomorphic)
|
|
670
|
-
|
|
671
|
-
```python
|
|
672
|
-
#!/usr/bin/env python3
|
|
673
|
-
"""同态加密示例(简化)"""
|
|
674
|
-
from typing import List
|
|
675
|
-
|
|
676
|
-
class SimpleHomomorphic:
|
|
677
|
-
"""简化的加法同态加密"""
|
|
678
|
-
|
|
679
|
-
def __init__(self, public_key: int, private_key: int):
|
|
680
|
-
self.public_key = public_key
|
|
681
|
-
self.private_key = private_key
|
|
682
|
-
|
|
683
|
-
def encrypt(self, plaintext: int) -> int:
|
|
684
|
-
"""加密"""
|
|
685
|
-
# 简化实现,实际应使用 Paillier 等算法
|
|
686
|
-
return (plaintext * self.public_key) % 1000000007
|
|
687
|
-
|
|
688
|
-
def decrypt(self, ciphertext: int) -> int:
|
|
689
|
-
"""解密"""
|
|
690
|
-
return (ciphertext * self.private_key) % 1000000007
|
|
691
|
-
|
|
692
|
-
def add_encrypted(self, c1: int, c2: int) -> int:
|
|
693
|
-
"""在密文上执行加法"""
|
|
694
|
-
return (c1 + c2) % 1000000007
|
|
695
|
-
|
|
696
|
-
# 使用示例
|
|
697
|
-
he = SimpleHomomorphic(public_key=123, private_key=456)
|
|
698
|
-
|
|
699
|
-
# 加密两个数
|
|
700
|
-
enc1 = he.encrypt(10)
|
|
701
|
-
enc2 = he.encrypt(20)
|
|
702
|
-
|
|
703
|
-
# 在密文上相加
|
|
704
|
-
enc_sum = he.add_encrypted(enc1, enc2)
|
|
705
|
-
|
|
706
|
-
# 解密结果
|
|
707
|
-
result = he.decrypt(enc_sum)
|
|
708
|
-
print(f"10 + 20 = {result}")
|
|
709
|
-
```
|
|
710
|
-
|
|
711
|
-
## Kubernetes Secrets
|
|
712
|
-
|
|
713
|
-
### External Secrets Operator
|
|
714
|
-
|
|
715
|
-
```yaml
|
|
716
|
-
# external-secret.yaml
|
|
717
|
-
apiVersion: external-secrets.io/v1beta1
|
|
718
|
-
kind: SecretStore
|
|
719
|
-
metadata:
|
|
720
|
-
name: vault-backend
|
|
721
|
-
spec:
|
|
722
|
-
provider:
|
|
723
|
-
vault:
|
|
724
|
-
server: "https://vault.example.com:8200"
|
|
725
|
-
path: "secret"
|
|
726
|
-
version: "v2"
|
|
727
|
-
auth:
|
|
728
|
-
kubernetes:
|
|
729
|
-
mountPath: "kubernetes"
|
|
730
|
-
role: "myapp"
|
|
731
|
-
---
|
|
732
|
-
apiVersion: external-secrets.io/v1beta1
|
|
733
|
-
kind: ExternalSecret
|
|
734
|
-
metadata:
|
|
735
|
-
name: myapp-secrets
|
|
736
|
-
spec:
|
|
737
|
-
refreshInterval: 1h
|
|
738
|
-
secretStoreRef:
|
|
739
|
-
name: vault-backend
|
|
740
|
-
kind: SecretStore
|
|
741
|
-
target:
|
|
742
|
-
name: myapp-secrets
|
|
743
|
-
creationPolicy: Owner
|
|
744
|
-
data:
|
|
745
|
-
- secretKey: db_password
|
|
746
|
-
remoteRef:
|
|
747
|
-
key: myapp/config
|
|
748
|
-
property: db_password
|
|
749
|
-
- secretKey: api_key
|
|
750
|
-
remoteRef:
|
|
751
|
-
key: myapp/config
|
|
752
|
-
property: api_key
|
|
753
|
-
```
|
|
754
|
-
|
|
755
|
-
### Sealed Secrets
|
|
756
|
-
|
|
757
|
-
```bash
|
|
758
|
-
# 安装 Sealed Secrets
|
|
759
|
-
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
|
|
760
|
-
|
|
761
|
-
# 安装 kubeseal CLI
|
|
762
|
-
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-linux-amd64
|
|
763
|
-
chmod +x kubeseal-linux-amd64
|
|
764
|
-
sudo mv kubeseal-linux-amd64 /usr/local/bin/kubeseal
|
|
765
|
-
|
|
766
|
-
# 创建 Secret
|
|
767
|
-
kubectl create secret generic mysecret \
|
|
768
|
-
--from-literal=password=supersecret \
|
|
769
|
-
--dry-run=client -o yaml > secret.yaml
|
|
770
|
-
|
|
771
|
-
# 加密 Secret
|
|
772
|
-
kubeseal -f secret.yaml -w sealed-secret.yaml
|
|
773
|
-
|
|
774
|
-
# 应用 Sealed Secret
|
|
775
|
-
kubectl apply -f sealed-secret.yaml
|
|
776
|
-
```
|
|
777
|
-
|
|
778
|
-
## 工具清单
|
|
779
|
-
|
|
780
|
-
| 工具 | 类型 | 特点 |
|
|
781
|
-
|------|------|------|
|
|
782
|
-
| HashiCorp Vault | 平台 | 动态密钥、多后端 |
|
|
783
|
-
| AWS KMS | 云服务 | 托管密钥、信封加密 |
|
|
784
|
-
| AWS Secrets Manager | 云服务 | 自动轮转、集成 |
|
|
785
|
-
| Azure Key Vault | 云服务 | HSM 支持 |
|
|
786
|
-
| GCP Secret Manager | 云服务 | IAM 集成 |
|
|
787
|
-
| CyberArk | 企业 | PAM 解决方案 |
|
|
788
|
-
| Sealed Secrets | K8s | GitOps 友好 |
|
|
789
|
-
| External Secrets | K8s | 多后端同步 |
|
|
790
|
-
|
|
791
|
-
## 最佳实践
|
|
792
|
-
|
|
793
|
-
### 密钥管理检查清单
|
|
794
|
-
|
|
795
|
-
```markdown
|
|
796
|
-
## 生成与存储
|
|
797
|
-
- [ ] 使用加密强随机数生成器
|
|
798
|
-
- [ ] 密钥长度符合标准(AES-256, RSA-2048+)
|
|
799
|
-
- [ ] 集中存储在密钥管理系统
|
|
800
|
-
- [ ] 启用静态加密
|
|
801
|
-
- [ ] 实施访问控制
|
|
802
|
-
|
|
803
|
-
## 分发与使用
|
|
804
|
-
- [ ] 最小权限原则
|
|
805
|
-
- [ ] 使用短期凭证
|
|
806
|
-
- [ ] 避免硬编码
|
|
807
|
-
- [ ] 环境变量或挂载卷
|
|
808
|
-
- [ ] 传输加密(TLS)
|
|
809
|
-
|
|
810
|
-
## 轮转与撤销
|
|
811
|
-
- [ ] 定期自动轮转
|
|
812
|
-
- [ ] 支持紧急撤销
|
|
813
|
-
- [ ] 轮转后验证
|
|
814
|
-
- [ ] 保留审计日志
|
|
815
|
-
- [ ] 通知相关方
|
|
816
|
-
|
|
817
|
-
## 监控与审计
|
|
818
|
-
- [ ] 记录所有访问
|
|
819
|
-
- [ ] 异常检测告警
|
|
820
|
-
- [ ] 定期审计
|
|
821
|
-
- [ ] 合规性检查
|
|
822
|
-
- [ ] 事件响应计划
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
### 密钥分类策略
|
|
826
|
-
|
|
827
|
-
| 级别 | 类型 | 轮转周期 | 存储 |
|
|
828
|
-
|------|------|----------|------|
|
|
829
|
-
| P0 | 根密钥、主密钥 | 年度 | HSM |
|
|
830
|
-
| P1 | 数据加密密钥 | 季度 | Vault |
|
|
831
|
-
| P2 | API 密钥 | 月度 | Secrets Manager |
|
|
832
|
-
| P3 | 会话令牌 | 小时 | Redis |
|
|
833
|
-
|
|
834
|
-
---
|