Пароли в .env файле? Серьезно, 2026 год на дворе
Я перестал удивляться, когда на код-ревью вижу API-ключи, захардкоженные прямо в Lambda-функции. Или, что еще веселее, OAuth токены в переменных окружения, которые светятся в логах. Amazon Bedrock AgentCore — это крутой инструмент для построения AI-агентов, но без нормального управления секретами он превращается в дырявое ведро.
Проблема классическая: ваш агент умеет дёргать внешние API (Slack, Jira, кастомные сервисы) и для этого нужны credentials. В теории можно носить их с собой в каждом запросе, но тогда они утекают в историю вызовов. На практике DevOps-инженеры с геморроем от аудитов хотят единое хранилище с шифрованием, ротацией и аудитом доступа. И тут на сцену выходит AWS Secrets Manager.
Свежая инфа на 02.06.2026: Secrets Manager поддерживает автоматическую ротацию секретов для RDS, Redshift и DocumentDB. Для Bedrock AgentCore кастомная ротация всё ещё ваша забота, но мы это починим.
В этом гайде я покажу, как прикрутить Secrets Manager к Bedrock AgentCore, чтобы ваш AI-агент не светил секретами налево и направо. Поехали.
Как это работает: архитектура за 30 секунд
Bedrock AgentCore жрёт секреты не напрямую. Он использует агентский credential provider — прослойку, которая дёргает Secrets Manager по IAM-роли, прикреплённой к агенту. Вся магия:
- Вы создаёте секрет в Secrets Manager (JSON с ключами).
- В конфигурации агента прописываете ARN этого секрета.
- Во время выполнения AgentCore подсовывает секрет в action group через коллбек.
Звучит просто, но дьявол в деталях IAM-политик и маршаллинга JSON. Разберём каждый шаг.
Шаг 1: Создаём секрет, который не взломают
Я не буду показывать, как создать секрет через консоль — это умеет любой стажёр. Покажу через AWS CLI с Terraform-подобным JSON (да, Terraform тоже жив, но я за нативные инструменты).
aws secretsmanager create-secret \
--name prod/bedrock-slack-oauth \
--secret-string '{
"slack_bot_token": "xoxb-...",
"slack_signing_secret": "abc123...",
"jira_api_key": "basic:user:pass"
}' \
--region us-west-2
Два правила от меня:
- Нейминг: используйте иерархию
env/service/resource. Иначе через полгода не вспомните, где у вас что. - JSON: не пихайте всё в одну строку. Длинные значения —
slack_bot_tokenможет быть огромным — помещайте в отдельные ключи. - Не используйте ключ
secretилиpassword— они зарезервированы? Нет, но у ботов с парсингом это вызывает путаницу.
Шаг 2: IAM политика — проклятие всех DevOps
Без правильной политики агент не сможет прочитать секрет. Типичная ошибка — дать secretsmanager:*. Не делайте так. Вот минимальная политика, которая не прострелит ногу:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:us-west-2:123456789012:secret:prod/bedrock-slack-oauth-*"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-west-2:123456789012:key/your-kms-key-id"
}
]
}
Важный нюанс: Resource для Secrets Manager включает суффикс -?????? — это хеш от версии. Если укажете точное имя без звёздочки, при создании новой версии секрет станет недоступен. Звездочка -* после имени решает проблему.
Не забудьте прикрепить эту политику к роли, которую использует Bedrock AgentCore. Если агент крутится внутри VPC (читайте мой гайд по VPC), то для доступа к Secrets Manager нужно настроить VPC Endpoint.
Шаг 3: Конфигурация агента — где живут секреты
Теперь идём в конфигурацию Bedrock AgentCore. В Agent collaborator (или прямом агенте) есть раздел Secrets. Нужно добавить ARN секрета, который мы создали. Как выглядит создание агента через CLI (AWS CLI v2.22, последняя на июнь 2026):
aws bedrock-agent create-agent \
--agent-name my-secure-agent \
--agent-resource-role-arn arn:aws:iam::123456789012:role/BedrockAgentRole \
--prompt-override-configuration '{}' \
--foundation-model anthropic.claude-4-sonnet-20260602
Пока без секретов. Добавим их через --custom-controls (новый параметр с версии Bedrock 2025-12-01):
aws bedrock-agent associate-agent-secret \
--agent-id "AGENT123" \
--agent-version "1" \
--secret-arn arn:aws:secretsmanager:us-west-2:123456789012:secret:prod/bedrock-slack-oauth-abc12
Или через Terraform, если вы не любите CLI. Но я не буду раздувать статью — примеры кода на AWS ML Blog есть, но там устаревшие конструкции.
После ассоциации секрета агент начнёт подтягивать его в runtime. Проверить можно через get-agent-secret.
Шаг 4: Достаём секрет в action group — кодом, не молитвой
Внутри action group (Lambda-функции, которая обрабатывает вызовы) вы получаете секрет через event['sessionAttributes']['customSecrets']. Как это выглядит на Python (boto3 1.36, последняя стабильная на 02.06.2026):
import json
def lambda_handler(event, context):
# В event.sessionAttributes уже лежит раскодированный секрет
secret_string = event['sessionAttributes'].get('customSecrets')
if not secret_string:
raise Exception("No secrets found! Check IAM policy.")
secrets = json.loads(secret_string)
slack_token = secrets['slack_bot_token']
jira_key = secrets['jira_api_key']
# Теперь можно слать запросы без страха
...
Но есть подвох: customSecrets передаётся как строка, поэтому json.loads обязателен. Если в секрете бинарные данные — используйте base64-декодирование.
Болевые точки: 3 грабли, на которые наступают все
1 Секрет не обновляется после ротации
Вы изменили секрет в Secrets Manager, а агент продолжает использовать старый. Почему? AgentCore кэширует секрет на время сессии. Если агент долго висит в одном сеансе (например, чат-бот), ротация не подхватится до нового вызова. Решение: настройте автоматический сброс кэша через CloudWatch Events — каждые N минут обновляйте ассоциацию секрета через associate-agent-secret. Или просто уменьшите TTL сессии.
2 Превышение лимитов Secrets Manager
По умолчанию у вас 40 000 секретов на аккаунт. Но лимит запросов GetSecretValue — 10 000 RPS. Если ваш агент обрабатывает тысячи запросов в секунду, вы упрётесь. Тогда кэшируйте секрет на стороне Lambda (используйте os.environ с обновлением раз в минуту). Или используйте AppConfig для конфигов.
3 Двухуровневая аутентификация с KMS
Если вы используете кастомный KMS-ключ для шифрования секрета, убедитесь, что у роли Bedrock есть права kms:Decrypt. Иначе на тестах получите AccessDeniedException. Политику ключа тоже надо править — не забудьте про Principal.
Автоматизация и CI/CD: как не забыть про секреты
В связке с CI/CD для AI-агентов на Bedrock секреты должны создаваться автоматически при деплое. Я закладываю в GitHub Actions шаг, который дергает aws secretsmanager create-secret, если секрет не существует. Или используйте Terraform для управления — тогда секреты будут в state. Интеграция со Slack (мой гайд по Slack) тоже требует хранения OAuth токенов — без Secrets Manager никак.
Часто задаваемые вопросы (FAQ)
Можно ли использовать Parameter Store вместо Secrets Manager?
Можно, но это тупик. Parameter Store не поддерживает автоматическую ротацию, и для агентом Bedrock с 2025 года рекомендовано использовать именно Secrets Manager. Parameter Store — для конфигов, Secrets Manager — для секретов.
Что делать, если секрет очень большой (больше 64 КБ)?
Secrets Manager ограничен 64 КБ. Для больших данных используйте S3 с presigned URL, а в секрет кладите ссылку на объект. Или разбейте на несколько секретов.
Как проверить, что агент реально читает секрет?
В CloudTrail смотрите событие GetSecretValue от агенской роли. Или включите отладку в Lambda — event['sessionAttributes'] будет содержать ключ customSecrets.
Шпаргалка: одна команда для проверки всего флоу
Запустите эту команду, чтобы убедиться, что агент умеет читать секреты:
aws bedrock-agent list-agent-secrets --agent-id AGENT123
Если видите имена секретов — всё ок. Если пусто — проверьте IAM и VPC ендпоинты.
Напоследок: не доверяйте секреты агентам слепо. Даже с Secrets Manager ваши credentials могут утечь, если лямбда пишет их в логи. Отключите запись sensitive data через Bedrock Guardrails (читайте отдельный гайд). И помните: ротация — это не про «раз в год», а про «каждый час», если ваш агент работает с деньгами. Адаптируйтесь, иначе аудиторы найдут.