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

Управление секретами через Python SDK

Что такое Python SDK

Python SDK — библиотека для программной работы с Пассворком. Подходит для сложной автоматизации, где возможностей CLI недостаточно.

ВозможностьОписание
Чтение секретовПолучение паролей, полей, вложений по ID или поиску
Изменение секретовОбновление паролей, полей, тегов, описаний
Создание секретовПрограммное создание записей в нужных папках
Управление структуройРабота с папками, сейфами, перемещение записей

Когда использовать SDK, а когда CLI

СценарийРекомендация
CI/CD-пайплайн, деплой-скриптpasswork-cli — проще, не требует кода
Ротация паролей с логикойPython SDK — гибкость, обработка ошибок
Миграция из другой системыPython SDK — преобразование данных
Проверка целостности секретовPython SDK — сложная логика валидации
Получение одного секрета в bashpasswork-cli get — одна команда

Установка

Установка через pip из gitVerse:

# SSH
pip install git+ssh://git@gitverse.ru:2222/passwork-ru/passwork-python.git

# HTTPS
pip install git+https://gitverse.ru/passwork-ru/passwork-python.git

Подробнее: Python-коннектор.

Инициализация клиента

from passwork import Client

client = Client(
url="https://passwork.example.com",
token="your_access_token",
)
подсказка

Не храните токен в коде. Используйте переменные окружения:

import os
from passwork import Client

client = Client(
url=os.environ["PASSWORK_HOST"],
token=os.environ["PASSWORK_TOKEN"],
)

Чтение секретов

По ID записи

item = client.get_password(item_id="<item-id>")

# Стандартные поля
print(item.login)
print(item.password)

# Пользовательские поля
db_host = item.fields["DB_HOST"]
api_key = item.fields["API_KEY"]

По папке

# Получить все записи из папки
items = client.list_folder_items(folder_id="<folder-id>")

for item in items:
print(f"{item.title}: {item.login}")

Поиск по строке

# Найти записи по части названия
items = client.search("app-db prod")

for item in items:
print(f"{item.id}: {item.title}")

Изменение секретов

Обновление существующей записи

# Получить запись
item = client.get_password(item_id="<item-id>")

# Изменить поля
item.password = "new-strong-password"
item.fields["API_KEY"] = "new-api-key"

# Сохранить
client.update_password(item)

Создание новой записи

client.create_password(
folder_id="<folder-id>",
title="Production DB",
login="app_user",
password="secure-password",
fields={
"DB_HOST": "db.example.com",
"DB_PORT": "5432",
},
tags=["prod", "database"],
)

Массовые операции

SDK позволяет автоматизировать:

  • перенос записей между папками;
  • массовое добавление/удаление тегов;
  • обновление полей по шаблону;
  • миграцию структуры secrets/*.
# Пример: добавить тег ко всем записям в папке
items = client.list_folder_items(folder_id="<folder-id>")

for item in items:
if "legacy" not in item.tags:
item.tags.append("legacy")
client.update_password(item)

Практические сценарии

Ротация пароля БД

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

import os
import secrets
import psycopg2
from passwork import Client

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

# Инициализация клиентов
client = Client(
url=os.environ["PASSWORK_HOST"],
token=os.environ["PASSWORK_TOKEN"],
)

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

# Получаем текущие credentials для подключения к БД
admin_item = client.get_password(item_id=os.environ["DB_ADMIN_ITEM_ID"])

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 Exception as e:
print(f"Rotation failed: {e}")
return False

# Запуск
rotate_db_password(
item_id="<item-id>",
db_role="app_user"
)

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

Скрипт для периодической проверки, что секреты актуальны:

import os
import psycopg2
from passwork import Client

def check_db_credentials(folder_id: str):
"""Проверка, что credentials в Пассворке рабочие."""

client = Client(
url=os.environ["PASSWORK_HOST"],
token=os.environ["PASSWORK_TOKEN"],
)

items = client.list_folder_items(folder_id=folder_id)
broken = []

for item in items:
if "database" not in item.tags:
continue

try:
conn = psycopg2.connect(
host=item.fields.get("DB_HOST"),
dbname=item.fields.get("DB_NAME", "postgres"),
user=item.login,
password=item.password,
connect_timeout=5,
)
conn.close()
print(f"✅ {item.title}")

except Exception as e:
print(f"❌ {item.title}: {e}")
broken.append(item)

# Помечаем запись тегом
if "needs-review" not in item.tags:
item.tags.append("needs-review")
client.update_password(item)

return broken

# Запуск
broken = check_db_credentials(folder_id="<secrets/prod/databases>")
if broken:
print(f"\n{len(broken)} secrets need review")

Миграция из файлов

Импорт секретов из .env файлов в Пассворк:

import os
from pathlib import Path
from passwork import Client

def migrate_env_file(env_path: str, folder_id: str, tags: list):
"""Импорт секретов из .env файла в Пассворк."""

client = Client(
url=os.environ["PASSWORK_HOST"],
token=os.environ["PASSWORK_TOKEN"],
)

env_file = Path(env_path)
secrets_dict = {}

# Парсим .env файл
for line in env_file.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", 1)
secrets_dict[key.strip()] = value.strip().strip('"\'')

# Создаём запись в Пассворке
client.create_password(
folder_id=folder_id,
title=env_file.stem,
fields=secrets_dict,
tags=tags,
)

print(f"Imported {len(secrets_dict)} secrets from {env_path}")

# Пример использования
migrate_env_file(
env_path="./legacy/.env.production",
folder_id="<secrets/prod/app1>",
tags=["prod", "migrated"],
)