ЁЯЧЭя╕П рдзрдбрд╛ 07 тАФ Secrets рдЖрдгрд┐ KMS: keys рддрд┐рдЬреЛрд░реАрдд, code рдордзреНрдпреЗ рдирд╛рд╣реА
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 16 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧреЗ: lesson-06-authorization ┬╖ рдкреБрдвреЗ: lesson-08-iam-network
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ06, рдЖрдгрд┐ рдЗрдорд╛рд░рдд рдЦрд┐рдбрдХреАрдЪрд╛ рдкрд╣рд┐рд▓рд╛ рдзрдбрд╛. рджреЛрди рдХрд╛рдореЗ. рдкрд╣рд┐рд▓реЗ,
envelope encryption: рдПрдХ рддрд╛рдЬреА data key data encrypt рдХрд░рддреЗ, рдЖрдгрд┐ KMS рдХрдзреАрдЪ рди рд╕реЛрдбрдгрд╛рд░реА
master key рдлрдХреНрдд data key encrypt рдХрд░рддреЗ. рджреБрд╕рд░реЗ, рдЧреБрдкрд┐рддреЗ (secrets) тАФ database passwords, API
keys тАФ files рдордзреНрдпреЗ рдирд╛рд╣реА, рддрд░ secret manager рдордзреНрдпреЗ рд░рд╛рд╣рддрд╛рдд, рдЖрдгрд┐ secret scanner code рдордзреНрдпреЗ
рдирд┐рд╕рдЯреВрди рдЖрд▓реЗрд▓реА рдЧреБрдкрд┐рддреЗ рд╢реЛрдзрддреЛ. sec/demo.py рдордзрд▓реЗ secrets() рджреЛрдиреНрд╣реА рджрд╛рдЦрд╡рддреЗ.
тЪая╕П sec/cloud.py рдордзрд▓рд╛ cipher рд╣рд╛ SHA-256 рдкрд╛рд╕реВрди рдмрдирд╡рд▓реЗрд▓рд╛ рд╢рд┐рдХрд╡рдгреНрдпрд╛рд╕рд╛рдареАрдЪрд╛ keystream рдЖрд╣реЗ. рддреЛ рдлрдХреНрдд envelope encryption рдЪрд╛ рдЖрдХрд╛рд░ рджрд╛рдЦрд╡рддреЛ. рддреНрдпрд╛рдд integrity check рдирд╛рд╣реА рдЖрдгрд┐ рддреНрдпрд╛рдиреЗ рдХрдзреАрд╣реА рдЦрд▒реНрдпрд╛ data рдЪреЗ рд╕рдВрд░рдХреНрд╖рдг рдХрд░реВ рдирдпреЗ. рдЦрд▒реНрдпрд╛ systems AWS KMS рдЖрдгрд┐ рддрдкрд╛рд╕рд▓реЗрд▓реА library (AES-256-GCM) рд╡рд╛рдкрд░рддрд╛рдд. рд╕реНрд╡рддрдГрдЪреА cryptography рдХрдзреАрд╣реА рд▓рд┐рд╣реВ рдирдХрд╛.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╢рд╛рд│рд╛ рдкреНрд░рдЧрддреАрдкреБрд╕реНрддрдХреЗ рдПрдХрд╛ рдХрдкрд╛рдЯрд╛рдд рдареЗрд╡рддреЗ. рдкреНрд░рддреНрдпреЗрдХ рдХрдкрд╛рдЯрд╛рдЪреА рд╕реНрд╡рддрдГрдЪреА рдЫреЛрдЯреА рдХрд┐рд▓реНрд▓реА рдЕрд╕рддреЗ (data key).
рдЫреЛрдЯреНрдпрд╛ рдХрд┐рд▓реНрд▓реНрдпрд╛ рдХрдкрд╛рдЯрд╛рдВрдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рдЦреБрдВрдЯреАрд╡рд░ рдЯрд╛рдВрдЧрд▓реНрдпрд╛ рддрд░ рдЪреЛрд░ рддреНрдпрд╛ рд╕рдЧрд│реНрдпрд╛ рдШреЗрдКрди рдЬрд╛рддреЛ. рдореНрд╣рдгреВрди office рдкреНрд░рддреНрдпреЗрдХ рдЫреЛрдЯреА рдХрд┐рд▓реНрд▓реА рдПрдХрд╛ рдЫреЛрдЯреНрдпрд╛ рдХреБрд▓реВрдкрдмрдВрдж рдбрдмреАрдд рдареЗрд╡рддреЗ, рдЖрдгрд┐ рддреНрдпрд╛ рдбрдмреНрдпрд╛ рдлрдХреНрдд рдореБрдЦреНрдп office рдЪреА рддрд┐рдЬреЛрд░реА рдЙрдШрдбреВ рд╢рдХрддреЗ (KMS рдордзрд▓реА master key). рдореБрдЦреНрдп office рдЪреА рддрд┐рдЬреЛрд░реА рдХрдзреАрдЪ рдореБрдЦреНрдп office рд╕реЛрдбрдд рдирд╛рд╣реА. рддреА рдЙрд╕рдиреА рдШреЗрддрд╛ рдпреЗрдд рдирд╛рд╣реА. рддреБрдореНрд╣реА рдлрдХреНрдд рдХреБрд▓реВрдкрдмрдВрдж рдбрдмреА рдШреЗрдКрди рдЬрд╛рдКрди рд╡рд┐рдЪрд╛рд░реВ рд╢рдХрддрд╛: "рдХреГрдкрдпрд╛ рд╣реА рдЙрдШрдбрд╛" тАФ рдЖрдгрд┐ рдореБрдЦреНрдп office рдХреЛрдгреА рд╡рд┐рдЪрд╛рд░рд▓реЗ, рдЖрдгрд┐ рдХрдзреА, рддреЗ рд▓рд┐рд╣реВрди рдареЗрд╡рддреЗ.
рдореНрд╣рдгреВрди рдкреНрд░рддреНрдпреЗрдХ рдХрдкрд╛рдЯрд╛рд╢реЗрдЬрд╛рд░реА рджреЛрди рдЧреЛрд╖реНрдЯреА рдЕрд╕рддрд╛рдд: рдХреБрд▓реВрдкрдмрдВрдж рдкреНрд░рдЧрддреАрдкреБрд╕реНрддрдХреЗ, рдЖрдгрд┐ рддрд┐рдЪреНрдпрд╛ рдХреБрд▓реВрдкрдмрдВрдж рдбрдмреАрддрд▓реА рдЫреЛрдЯреА рдХрд┐рд▓реНрд▓реА. рджреЛрдиреНрд╣реА рдЪреЛрд░рдгрд╛рд▒реНрдпрд╛ рдЪреЛрд░рд╛рдХрдбреЗ рдЙрдШрдбрддрд╛ рдпреЗрдИрд▓ рдЕрд╕реЗ рдХрд╛рд╣реАрдЪ рдирд╕рддреЗ.
рдЖрдгрд┐ office рдПрдХ metal detector рдШреЗрдКрди рдлрд┐рд░рддреЗ (secret scanner). рдХреЛрдгреА noticeboard рд╡рд░ рдХрд┐рд▓реНрд▓реА рдЪрд┐рдХрдЯрд╡рд▓реА рдЕрд╕реЗрд▓ тАФ file рдордзрд▓рд╛ password тАФ рддрд░ рддреЛ рд╡рд╛рдЬрддреЛ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
pt["ЁЯУД Katrina: A+ in maths"] --> enc["ЁЯФР encrypt with data key"]
dk["ЁЯФС data key<br/>fresh per object"] --> enc
enc --> ct["ciphertext"]
dk --> wrap["ЁЯУж wrap with master key"]
kms["ЁЯПж KMS master key<br/>never leaves KMS"] --> wrap
wrap --> wk["wrapped data key"]
ct --> store["ЁЯЧДя╕П stored together:<br/>ciphertext + wrapped key"]
wk --> store
scan["ЁЯФН secret scanner<br/>AKIAтАж ┬╖ PRIVATE KEY ┬╖ password="] -.-> repo["ЁЯУБ repo files"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/security/lesson-diagrams.html#l07
тЭУ рдХрд╛рдп
- Secret (рдЧреБрдкрд┐рдд) тАФ access рджреЗрдгрд╛рд░реА рдХреЛрдгрддреАрд╣реА рдЧреЛрд╖реНрдЯ: database password, API key, signing key, cloud access key, private TLS key.
- Secret manager тАФ рдЧреБрдкрд┐рддреЗ encrypted рд╕рд╛рдард╡рдгрд╛рд░реА, рдкреНрд░рддреНрдпреЗрдХ рдЧреБрдкрд┐рдд рдХреЛрдг рд╡рд╛рдЪреВ рд╢рдХрддреЛ рддреЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдгрд╛рд░реА (IAM), рдкреНрд░рддреНрдпреЗрдХ рд╡рд╛рдЪрдирд╛рдЪрд╛ log рдареЗрд╡рдгрд╛рд░реА, рдЖрдгрд┐ рддреНрдпрд╛рдВрдирд╛ rotate рдХрд░рдгрд╛рд░реА service: AWS Secrets Manager, AWS Systems Manager Parameter Store (SecureString), HashiCorp Vault, Azure Key Vault, Google Secret Manager. App рд╕реНрд╡рддрдГрдЪреНрдпрд╛ role рдиреЗ рдЧреБрдкрд┐рдд runtime рд▓рд╛ рдЖрдгрддреЗ тАФ image рдХрд┐рдВрд╡рд╛ repo рдордзреНрдпреЗ рдХрд╛рд╣реАрдЪ рдирд╕рддреЗ.
- Rotation тАФ рдард░рд▓реЗрд▓реНрдпрд╛ рд╡реЗрд│рд╛рдкрддреНрд░рдХрд╛рдиреЗ, рдЖрдгрд┐ leak рдирдВрддрд░ рд▓рдЧреЗрдЪ, рдЧреБрдкрд┐рдд рдмрджрд▓рдгреЗ. рддреНрдпрд╛рд╣реВрдирд╣реА рдЪрд╛рдВрдЧрд▓реЗ: рдЖрдкреЛрдЖрдк expire рд╣реЛрдгрд╛рд░реА рдЕрд▓реНрдкрд╛рдпреБрд╖реА credentials (IAM roles, Vault dynamic database users).
- KMS (key management service) тАФ master keys (AWS рддреНрдпрд╛рдВрдирд╛ KMS keys рдореНрд╣рдгрддреЗ) hardware security modules рдордзреНрдпреЗ рдареЗрд╡рддреЗ. рддреБрдореНрд╣рд╛рд▓рд╛ key рдХрдзреАрдЪ рджрд┐рд╕рдд рдирд╛рд╣реА; рддреБрдореНрд╣реА KMS рд▓рд╛ рддреА рд╡рд╛рдкрд░рд╛рдпрд▓рд╛ рд╕рд╛рдВрдЧрддрд╛, рдЖрдгрд┐ CloudTrail рдкреНрд░рддреНрдпреЗрдХ request рдЪрд╛ log рдареЗрд╡рддреЛ. Key policies рдЖрдгрд┐ IAM рдХреЛрдг рд╣реЗ рдХрд░реВ рд╢рдХрддреЛ рддреЗ рдард░рд╡рддрд╛рдд.
- Envelope encryption тАФ KMS рдереЗрдЯ рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд 4 KB encrypt рдХрд░рддреЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ call рд╣реА network
request рдЕрд╕рддреЗ. рдореНрд╣рдгреВрди:
- KMS рдХрдбреВрди data key рдорд╛рдЧрд╛ (
GenerateDataKey): рддреА рддреБрдореНрд╣рд╛рд▓рд╛ plain text рдордзреНрдпреЗ рдЖрдгрд┐ wrapped (master key рдЦрд╛рд▓реА encrypted) рдЕрд╢реА рджреЛрдиреНрд╣реА рд░реВрдкрд╛рдд рдорд┐рд│рддреЗ, - plain data key рдиреЗ data local рдкрд╛рддрд│реАрд╡рд░ encrypt рдХрд░рд╛ (AES-GCM), рдордЧ plain key рд╡рд┐рд╕рд░реВрди рдЬрд╛,
- ciphertext wrapped key рд╕реЛрдмрдд рд╕рд╛рдард╡рд╛,
- рд╡рд╛рдЪрдгреНрдпрд╛рд╕рд╛рдареА: wrapped key KMS рд▓рд╛ рдкрд╛рдард╡рд╛ (
Decrypt), plain data key рдкрд░рдд рдорд┐рд│рд╡рд╛, local рдкрд╛рддрд│реАрд╡рд░ decrypt рдХрд░рд╛. KMS рд╕рд╣ S3, EBS, RDS рдЖрдгрд┐ DynamoDB encryption рд╕рдЧрд│реЗ рдпрд╛рдЪ рдкрджреНрдзрддреАрдиреЗ рдХрд╛рдо рдХрд░рддрд╛рдд.
- KMS рдХрдбреВрди data key рдорд╛рдЧрд╛ (
- Secret scanning тАФ code рдЖрдгрд┐ history рдордзреНрдпреЗ patterns рд╢реЛрдзрдгреЗ: AWS access key ids (
AKIAтАж), private key headers, URLs рдордзрд▓реЗ passwords,password = "тАж". рддреЛ commit рдЖрдзреА рдЪрд╛рд▓рд╡рд╛ (pre-commit hook), CI рдордзреНрдпреЗ, рдЖрдгрд┐ host рдЪреНрдпрд╛ push protection рд╕рд╣. OWASP Top 10 (2021) A02:2021 тАУ Cryptographic Failures рд╕рдВрд░рдХреНрд╖рд┐рдд рдирд╕рд▓реЗрд▓реНрдпрд╛ keys рдЖрдгрд┐ data рд▓рд╛ рд▓рд╛рдЧреВ рд╣реЛрддреЗ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг code рдордзрд▓реА рдЧреБрдкрд┐рддреЗ code рдЬрд┐рдереЗ рдЬрд╛рддреЛ рддрд┐рдереЗ рд╕рдЧрд│реАрдХрдбреЗ рдЬрд╛рддрд╛рдд: рдкреНрд░рддреНрдпреЗрдХ laptop, рдкреНрд░рддреНрдпреЗрдХ fork, рдкреНрд░рддреНрдпреЗрдХ
CI log, рдкреНрд░рддреНрдпреЗрдХ container image тАФ рдЖрдгрд┐ рддреБрдореНрд╣реА рдУрд│ delete рдХреЗрд▓реНрдпрд╛рдирдВрддрд░рд╣реА git history рддреА рдареЗрд╡рддреЗ.
рдХрд╛рд░рдг manager рддреБрдореНрд╣рд╛рд▓рд╛ files рджреЗрдК рд╢рдХрдд рдирд╛рд╣реАрдд рддреЗ рджреЗрддреЛ: рдЧреБрдкрд┐рдд рдХреЛрдгреА рд╡рд╛рдЪрд▓реЗ, release рд╢рд┐рд╡рд╛рдп рддреЗ
рдмрджрд▓рдгреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ, рдЖрдгрд┐ access рдХрд╛рдвреВрди рдШреЗрдгреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ. рдЖрдгрд┐ рдХрд╛рд░рдг envelope encryption рдорд╣рддреНрддреНрд╡рд╛рдЪреА
рдПрдХрдореЗрд╡ key KMS рдЪреНрдпрд╛ рдЖрдд рдареЗрд╡рддреЗ: data рд╡рд╛рдЪрдгреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдард╡рд▓реЗрд▓рд╛ blob рдЖрдгрд┐
kms:Decrypt call рдХрд░рдгреНрдпрд╛рдЪреА permission рджреЛрдиреНрд╣реА рд▓рд╛рдЧрддрд╛рдд тАФ рдЬреА рддреБрдореНрд╣реА audit рдХрд░реВ рд╢рдХрддрд╛, рдЖрдгрд┐ revoke рдХрд░реВ рд╢рдХрддрд╛.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
sec/cloud.py рдордзреНрдпреЗ: envelope_encrypt(plaintext, master_key, data_key)
ciphertext (data key рдЦрд╛рд▓рдЪрд╛ data) рдЖрдгрд┐ wrapped_key (master key рдЦрд╛рд▓рдЪреА data key) рдкрд░рдд рджреЗрддреЗ.
envelope_decrypt(blob, master_key) рдЖрдзреА data key рдЙрдШрдбрддреЗ, рдордЧ decrypt рдХрд░рддреЗ тАФ kms:Decrypt +
local decryption рд╕рд╛рд░рдЦреНрдпрд╛рдЪ рджреЛрди рдкрд╛рдпрд▒реНрдпрд╛. find_secrets(files) {filename: text} рдЪреНрдпрд╛ dict рд╡рд░ рдЪрд╛рд░ regular
expressions рдЪрд╛рд▓рд╡рддреЗ рдЖрдгрд┐ (file, kind) рдЬреЛрдбреНрдпрд╛ рдкрд░рдд рджреЗрддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 sec/demo.py secrets
python3 - <<'EOF'
import sys; sys.path.insert(0, "sec"); from cloud import envelope_encrypt, envelope_decrypt, find_secrets
blob = envelope_encrypt("Dipika: B+ in maths", master_key=b"kms-master-key", data_key=b"fresh-data-key-42")
print("stored next to the data:", sorted(blob))
print("right master key тЖТ", envelope_decrypt(blob, b"kms-master-key"))
try:
print("wrong master key тЖТ", envelope_decrypt(blob, b"guess"))
except UnicodeDecodeError:
print("wrong master key тЖТ unreadable bytes")
files = {"settings.py": 'DB_PASSWORD = os.environ["DB_PASSWORD"]',
"docker-compose.yml": "DATABASE_URL: postgres://app:Winter2026@db:5432/school",
"test_login.py": 'token = "abc"',
"old.env": "API_TOKEN='sk_live_0123456789abcdef'"}
for name, kind in find_secrets(files): print(f"found: {name:<20} {kind}")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
secrets рд╣реЗ print рдХрд░рддреЗ:
тФАтФА envelope encryption: ciphertext fe1cf83a01159db61697тАж ┬╖ wrapped data key 00d66fb446efd05f5b12тАж
decrypt = unwrap the data key with the master key (KMS) тЖТ 'Katrina: A+ in maths'
тФАтФА secret scan of 4 files тЖТ [('config.py', 'generic secret'), ('deploy.sh', 'AWS access key id'), ('notes.md', 'private key')]
secrets live in a manager (Secrets Manager / Vault), are fetched at runtime, rotated, and never committed
рддреБрдордЪрд╛ snippet рд╣реЗ print рдХрд░рддреЛ:
stored next to the data: ['ciphertext', 'wrapped_key']
right master key тЖТ Dipika: B+ in maths
wrong master key тЖТ unreadable bytes
found: docker-compose.yml password in a URL
found: old.env generic secret
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдлрдХреНрдд рджреЛрдирдЪ рдЧреЛрд╖реНрдЯреА рд╕рд╛рдард╡рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд тАФ ciphertext рдЖрдгрд┐ wrapped key; plain data key
рдирд┐рдШреВрди рдЧреЗрд▓реА рдЖрд╣реЗ. Master key рд╢рд┐рд╡рд╛рдп data рд╡рд╛рдЪрддрд╛ рдпреЗрдд рдирд╛рд╣реА. Scanner рд▓рд╛ database URL рдордзрд▓рд╛
password рдЖрдгрд┐ рдЬреБрдиреНрдпрд╛ .env file рдордзрд▓рд╛ token рд╕рд╛рдкрдбрд▓рд╛. рддреНрдпрд╛рдиреЗ environment рдордзреВрди password рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛
settings.py рд▓рд╛, рдХрд┐рдВрд╡рд╛ 3 рдЕрдХреНрд╖рд░рд╛рдВрдЪреНрдпрд╛ test value рд▓рд╛ flag рдХреЗрд▓реЗ рдирд╛рд╣реА.
Scanners patterns рдЖрдгрд┐ рд▓рд╛рдВрдмреАрдЪреЗ рдирд┐рдпрдо рд╡рд╛рдкрд░рддрд╛рдд тАФ рддреЗ рдЕрдиреЗрдХ leaks рдкрдХрдбрддрд╛рдд, рд╕рдЧрд│реЗ рдирд╛рд╣реА, рдореНрд╣рдгреВрди рддреЗ рдПрдХ
рдерд░ рдЖрд╣реЗрдд, рд╕рдВрдкреВрд░реНрдг рдЖрд░рд╛рдЦрдбрд╛ рдирд╛рд╣реА.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- "рдлрдХреНрдд рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рд╕рд╛рдареА" repo рдордзреНрдпреЗ рдЧреБрдкрд┐рддреЗ, рдХрд┐рдВрд╡рд╛
docker-compose.ymlрдордзреНрдпреЗ, рдХрд┐рдВрд╡рд╛ image рдордзреНрдпреЗ рднрд╛рдЬреВрди рдЯрд╛рдХрд▓реЗрд▓реА - рдУрд│ delete рдХрд░реВрди рдкреБрдиреНрд╣рд╛ push рдХрд░рдгреЗ тАФ рдЧреБрдкрд┐рдд рдЕрдЬреВрдирд╣реА git history, forks рдЖрдгрд┐ caches рдордзреНрдпреЗ рдЖрд╣реЗ (рдзрдбрд╛ 15: рдЖрдзреА rotate рдХрд░рд╛)
- рдкреНрд░рддреНрдпреЗрдХ service рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ developer рд╕рд╛рдареА рдПрдХрдЪ shared database password
- environment variables рдордзрд▓реА рдЧреБрдкрд┐рддреЗ рдЬреА рдирдВрддрд░ crash reports, logs рдХрд┐рдВрд╡рд╛
psoutput рдордзреНрдпреЗ рджрд┐рд╕рддрд╛рдд - рддрдкрд╛рд╕рд▓реЗрд▓реНрдпрд╛ library рдордзрд▓реНрдпрд╛ KMS + AES-GCM рдРрд╡рдЬреА рд╕реНрд╡рддрдГрдЪреЗ encryption рд▓рд┐рд╣рд┐рдгреЗ
- account рдордзрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ role рд▓рд╛
kms:Decryptcall рдХрд░реВ рджреЗрдгрд╛рд░реА KMS key policy
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ database рдЧреБрдкрд┐рдд AWS Secrets Manager рдордзреНрдпреЗ, рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ KMS key рдиреЗ encrypted, рд╕рд╛рдард╡рд╛ рдЖрдгрд┐ automatic rotation рдЪрд╛рд▓реВ рдХрд░рд╛:
aws kms create-key --description "school secrets" # note the KeyId
aws kms create-alias --alias-name alias/school-secrets --target-key-id <KeyId>
aws kms enable-key-rotation --key-id <KeyId>
aws secretsmanager create-secret --name school/results-db \
--kms-key-id alias/school-secrets --secret-string file://results-db.json
aws secretsmanager rotate-secret --secret-id school/results-db \
--rotation-lambda-arn arn:aws:lambda:ap-south-1:111122223333:function:rotate-results-db \
--rotation-rules AutomaticallyAfterDays=30
App рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ IAM role рдиреЗ рддреЗ runtime рд▓рд╛ рд╡рд╛рдЪрд╛ (Python, boto3) тАФ code рдХрд┐рдВрд╡рд╛ image рдордзреНрдпреЗ рдХрд╛рд╣реАрдЪ рдирд╛рд╣реА:
import boto3, json
sm = boto3.client("secretsmanager")
db = json.loads(sm.get_secret_value(SecretId="school/results-db")["SecretString"])
KMS data key рдЖрдгрд┐ AES-256-GCM рд╕рд╣ envelope encryption (cryptography library):
import boto3, os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
kms = boto3.client("kms")
dk = kms.generate_data_key(KeyId="alias/school-data", KeySpec="AES_256")
nonce = os.urandom(12)
ciphertext = AESGCM(dk["Plaintext"]).encrypt(nonce, b"Katrina: A+ in maths", None)
record = {"ciphertext": ciphertext, "nonce": nonce, "wrapped_key": dk["CiphertextBlob"]}
del dk # never store the plain data key
# to read: key = kms.decrypt(CiphertextBlob=record["wrapped_key"])["Plaintext"]
# AESGCM(key).decrypt(record["nonce"], record["ciphertext"], None)
(AWS Encryption SDK рд╣реЗ рд╕рдЧрд│реЗ рддреБрдордЪреНрдпрд╛рд╕рд╛рдареА рдХрд░рддреЗ, key caching рд╕рд╣.)
рдЧреБрдкрд┐рддреЗ commit рд╣реЛрдгреНрдпрд╛рдЖрдзреАрдЪ рдерд╛рдВрдмрд╡рд╛ тАФ gitleaks рд╕рд╣ pre-commit hook:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleaks
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рддреБрдордЪреНрдпрд╛ code host рдЪреЗ secret scanning push protection рд╕рд╣ рдЪрд╛рд▓реВ рдХрд░рд╛, CI рдордзреНрдпреЗ рдПрдХрджрд╛ рдкреВрд░реНрдг history рд╡рд░ scanner рдЪрд╛рд▓рд╡рд╛, рдЖрдгрд┐ рд╕рд╛рдкрдбрд▓реЗрд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдЧреБрдкрд┐рдд manager рдордзреНрдпреЗ рд╣рд▓рд╡рд╛ тАФ рдЬрд╛рддрд╛ рдЬрд╛рддрд╛ рддреЗ rotate рдХрд░рдд. Access keys рдРрд╡рдЬреА IAM roles рд▓рд╛ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджреНрдпрд╛, рдореНрд╣рдгрдЬреЗ leak рд╣реЛрдгреНрдпрд╛рд╕рд╛рдареА рджреАрд░реНрдШрд╛рдпреБрд╖реА key рдореБрд│рд╛рддрдЪ рдирд╕реЗрд▓.
тПня╕П рдкреБрдвреЗ
рдЧреБрдкрд┐рдд рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ. рдкрдг рддреЗ рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛ role рд▓рд╛ рдЧрд░рдЬреЗрдкреЗрдХреНрд╖рд╛ рдЦреВрдк рдЬрд╛рд╕реНрдд рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рдЕрд╕реВ рд╢рдХрддреЗ, рдЖрдгрд┐ database рдХреБрдареВрдирд╣реА рдкреЛрд╣реЛрдЪрдгреНрдпрд╛рдЬреЛрдЧрд╛ рдЕрд╕реВ рд╢рдХрддреЛ. рдкреБрдвреЗ: рдХрд┐рдорд╛рди рдЕрдзрд┐рдХрд╛рд░ рдЖрдгрд┐ рдмрдВрдж рджрд╛рд░реЗ.
git checkout lesson-08-iam-network