Перейти к основному содержимому
Версия: 7.0

Практика ротации секретов

Зачем нужна ротация

Регулярная смена секретов снижает риски:

РискКак ротация помогает
Утечка пароляСкомпрометированный пароль быстро становится недействительным
Долгоживущие токеныОграничение времени жизни уменьшает окно атаки
Инсайдерские угрозыБывшие сотрудники теряют доступ после ротации
Compliance-требованияPCI DSS, SOC 2 требуют регулярной смены паролей

Принцип ротации

┌─────────────────────────────────────────────────────────────┐
│ 1. Генерация 2. Целевая система 3. Пассворк │
│ нового пароля (обновление) (сохранение) │
│ │
│ openssl rand ──► ALTER ROLE ... ──────► passwork-cli update│
└─────────────────────────────────────────────────────────────┘
Важно: порядок действий

Сначала обновите пароль в целевой системе (БД, сервис), затем в Пассворке. Иначе возникнет рассинхрон: Пассворк содержит новый пароль, а система ещё использует старый.

Ротация через CLI

PostgreSQL

#!/bin/bash
set -e

ITEM_ID="<item-id>"
DB_ROLE="app_user"

# 1. Генерируем новый пароль
NEW_PASS=$(openssl rand -base64 32)

# 2. Обновляем в PostgreSQL
psql -h db.example.com -U admin -d postgres -c \
"ALTER ROLE ${DB_ROLE} WITH PASSWORD '${NEW_PASS}';"

# 3. Сохраняем в Пассворк
passwork-cli update --password-id "${ITEM_ID}" --password "${NEW_PASS}"

echo "Password rotated for ${DB_ROLE}"

MySQL

#!/bin/bash
set -e

ITEM_ID="<item-id>"
DB_USER="app"

NEW_PASS=$(openssl rand -base64 32)

mysql -h db.example.com -u root -p"${MYSQL_ROOT_PASSWORD}" -e \
"ALTER USER '${DB_USER}'@'%' IDENTIFIED BY '${NEW_PASS}';"

passwork-cli update --password-id "${ITEM_ID}" --password "${NEW_PASS}"

echo "Password rotated for ${DB_USER}"

API-ключ

#!/bin/bash
set -e

ITEM_ID="<item-id>"

# 1. Запрашиваем новый ключ у внешнего сервиса
NEW_KEY=$(curl -s -X POST https://api.service.com/keys/rotate \
-H "Authorization: Bearer ${OLD_KEY}" | jq -r '.new_key')

# 2. Сохраняем в Пассворк
passwork-cli update --password-id "${ITEM_ID}" --password "${NEW_KEY}"

echo "API key rotated"

Ротация через Python SDK

Полный пример с обработкой ошибок:

#!/usr/bin/env python3
"""Скрипт ротации пароля PostgreSQL."""

import os
import secrets
import sys
import psycopg2
from passwork import Client


def rotate_password(item_id: str, db_role: str) -> bool:
"""
Ротация пароля для роли PostgreSQL.

Returns:
True при успехе, False при ошибке.
"""
# Инициализация
client = Client(
url=os.environ["PASSWORK_HOST"],
token=os.environ["PASSWORK_TOKEN"],
)

# Получаем admin credentials из Пассворка
admin_item = client.get_password(
item_id=os.environ["DB_ADMIN_ITEM_ID"]
)

# Генерируем новый пароль
new_password = secrets.token_urlsafe(32)

try:
# Подключаемся к PostgreSQL
conn = psycopg2.connect(
host=admin_item.fields["DB_HOST"],
dbname="postgres",
user=admin_item.login,
password=admin_item.password,
)
conn.autocommit = True

# Обновляем пароль в БД
with conn.cursor() as cur:
cur.execute(
"ALTER ROLE %s WITH PASSWORD %s",
(db_role, new_password)
)
conn.close()

# Сохраняем в Пассворк
item = client.get_password(item_id=item_id)
item.password = new_password
client.update_password(item)

print(f"Password rotated for {db_role}")
return True

except psycopg2.Error as e:
print(f"Database error: {e}", file=sys.stderr)
return False

except Exception as e:
print(f"Error: {e}", file=sys.stderr)
return False


if __name__ == "__main__":
success = rotate_password(
item_id=os.environ["TARGET_ITEM_ID"],
db_role=os.environ["DB_ROLE"],
)
sys.exit(0 if success else 1)

Автоматизация

Cron-задача

# /etc/cron.d/passwork-rotation
# Ротация паролей БД каждое воскресенье в 3:00

0 3 * * 0 passwork /opt/scripts/rotate-db-passwords.sh >> /var/log/rotation.log 2>&1

Рекомендации

Частота ротации

Тип секретаРекомендуемая частота
Пароли БД (production)30–90 дней
API-ключи внешних сервисов90 дней или по требованию сервиса
Сервисные токены7–30 дней
SSH-ключи6–12 месяцев