<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Документация Proto Observability Platform – секреты</title><link>/docs/tags/%D1%81%D0%B5%D0%BA%D1%80%D0%B5%D1%82%D1%8B/</link><description>Recent content in секреты on Документация Proto Observability Platform</description><generator>Hugo -- gohugo.io</generator><language>ru</language><atom:link href="/docs/tags/%D1%81%D0%B5%D0%BA%D1%80%D0%B5%D1%82%D1%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>Setup: Управление секретами в конфигурации агента</title><link>/docs/setup/agent/secrets/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>/docs/setup/agent/secrets/</guid><description>
&lt;p>На этой странице:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="#%d0%ba%d0%b0%d0%ba-%d1%8d%d1%82%d0%be-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d0%b5%d1%82">Как это работает&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b2%d1%8b%d0%b1%d0%be%d1%80-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1%d0%b0">Выбор способа&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89%d0%b0-secret_backend_type">Встроенные хранилища: secret_backend_type&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#%d1%84%d0%b0%d0%b9%d0%bb-yaml-%d0%b8%d0%bb%d0%b8-json">Файл YAML или JSON&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%ba%d0%b0%d1%82%d0%b0%d0%bb%d0%be%d0%b3-%d1%81-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0%d0%bc%d0%b8">Каталог с файлами&lt;/a>&lt;/li>
&lt;li>&lt;a href="#kubernetes-secrets">Kubernetes Secrets&lt;/a>&lt;/li>
&lt;li>&lt;a href="#hashicorp-vault">HashiCorp Vault&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b4%d1%80%d1%83%d0%b3%d0%b8%d0%b5-%d1%82%d0%b8%d0%bf%d1%8b">Другие типы&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#%d0%bd%d0%b5%d1%81%d0%ba%d0%be%d0%bb%d1%8c%d0%ba%d0%be-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89-multi_secret_backends">Несколько хранилищ: multi_secret_backends&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%81%d0%be%d0%b1%d1%81%d1%82%d0%b2%d0%b5%d0%bd%d0%bd%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-secret_backend_command">Собственная программа: secret_backend_command&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#%d0%bf%d1%80%d0%be%d1%82%d0%be%d0%ba%d0%be%d0%bb-%d0%be%d0%b1%d0%bc%d0%b5%d0%bd%d0%b0">Протокол обмена&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%82%d1%80%d0%b5%d0%b1%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-%d0%ba-%d0%bf%d1%80%d0%b0%d0%b2%d0%b0%d0%bc-%d0%bd%d0%b0-%d1%84%d0%b0%d0%b9%d0%bb">Требования к правам на файл&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%b3%d0%be%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d0%bd%d0%b8%d0%ba-%d0%b4%d0%bb%d1%8f-%d0%ba%d0%be%d0%bd%d1%82%d0%b5%d0%b9%d0%bd%d0%b5%d1%80%d0%be%d0%b2">Готовый помощник для контейнеров&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d1%81%d0%b5%d0%ba%d1%80%d0%b5%d1%82%d0%be%d0%b2-%d0%b1%d0%b5%d0%b7-%d0%bf%d0%b5%d1%80%d0%b5%d0%b7%d0%b0%d0%bf%d1%83%d1%81%d0%ba%d0%b0">Обновление секретов без перезапуска&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%be%d1%87%d0%bd%d0%b8%d0%ba-%d0%bf%d0%b0%d1%80%d0%b0%d0%bc%d0%b5%d1%82%d1%80%d0%be%d0%b2">Справочник параметров&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%ba%d0%b0-%d0%b8-%d0%b4%d0%b8%d0%b0%d0%b3%d0%bd%d0%be%d1%81%d1%82%d0%b8%d0%ba%d0%b0">Проверка и диагностика&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="как-это-работает">Как это работает&lt;/h2>
&lt;p>Вместо значения секрета в конфигурации указывается ссылка вида &lt;code>ENC[&amp;lt;идентификатор&amp;gt;]&lt;/code>. При запуске агент собирает все такие ссылки, запрашивает значения у источника секретов и подставляет их в конфигурацию в памяти. В файлах на диске секреты не появляются.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># /etc/protoobp-agent/protoobp.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">api_key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[protoobp_api_key]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># /etc/protoobp-agent/conf.d/postgres.d/conf.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">instances&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">host&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">localhost&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">port&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">5432&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">username&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">protoobp&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[postgres_password]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Правила использования ссылок:&lt;/p>
&lt;ul>
&lt;li>&lt;code>ENC[...]&lt;/code> должна занимать &lt;strong>всё значение&lt;/strong> параметра. Значение &lt;code>&amp;quot;pass-ENC[x]&amp;quot;&lt;/code> или &lt;code>&amp;quot;ENC[x]/path&amp;quot;&lt;/code> не распознаётся.&lt;/li>
&lt;li>Ссылки работают в &lt;code>protoobp.yaml&lt;/code>, в файлах интеграций &lt;code>conf.d/&amp;lt;интеграция&amp;gt;.d/conf.yaml&lt;/code> и в шаблонах &lt;a href="../autodiscovery/">автообнаружения&lt;/a> (лейблы контейнеров и аннотации подов).&lt;/li>
&lt;li>Идентификатор внутри скобок передаётся источнику секретов без изменений; его формат зависит от выбранного источника и описан ниже.&lt;/li>
&lt;/ul>
&lt;h2 id="выбор-способа">Выбор способа&lt;/h2>
&lt;p>Источник секретов задаётся одним из трёх параметров. Если задано несколько, действует первый по порядку, остальные игнорируются с предупреждением в журнале агента.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Приоритет&lt;/th>
&lt;th style="text-align:left">Параметр&lt;/th>
&lt;th style="text-align:left">Когда использовать&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">1&lt;/td>
&lt;td style="text-align:left">&lt;a href="#%d1%81%d0%be%d0%b1%d1%81%d1%82%d0%b2%d0%b5%d0%bd%d0%bd%d0%b0%d1%8f-%d0%bf%d1%80%d0%be%d0%b3%d1%80%d0%b0%d0%bc%d0%bc%d0%b0-secret_backend_command">&lt;code>secret_backend_command&lt;/code>&lt;/a>&lt;/td>
&lt;td style="text-align:left">Нужен источник, которого нет среди встроенных, или уже есть собственный скрипт&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">2&lt;/td>
&lt;td style="text-align:left">&lt;a href="#%d0%b2%d1%81%d1%82%d1%80%d0%be%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89%d0%b0-secret_backend_type">&lt;code>secret_backend_type&lt;/code>&lt;/a>&lt;/td>
&lt;td style="text-align:left">Все секреты лежат в одном поддерживаемом хранилище&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">3&lt;/td>
&lt;td style="text-align:left">&lt;a href="#%d0%bd%d0%b5%d1%81%d0%ba%d0%be%d0%bb%d1%8c%d0%ba%d0%be-%d1%85%d1%80%d0%b0%d0%bd%d0%b8%d0%bb%d0%b8%d1%89-multi_secret_backends">&lt;code>multi_secret_backends&lt;/code>&lt;/a>&lt;/td>
&lt;td style="text-align:left">Секреты распределены по нескольким хранилищам&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="встроенные-хранилища-secret_backend_type">Встроенные хранилища: secret_backend_type&lt;/h2>
&lt;p>Для встроенных хранилищ писать программу не нужно: агент использует поставляемый в пакете исполняемый файл &lt;code>secret-generic-connector&lt;/code> (Linux — &lt;code>/opt/protoobp-agent/embedded/bin/&lt;/code>, Windows — каталог &lt;code>bin\agent&lt;/code> установки агента). Тип хранилища задаётся в &lt;code>secret_backend_type&lt;/code>, его параметры — в &lt;code>secret_backend_config&lt;/code>.&lt;/p>
&lt;h3 id="файл-yaml-или-json">Файл YAML или JSON&lt;/h3>
&lt;p>Секреты хранятся в одном файле в виде плоского словаря «идентификатор: значение».&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># /etc/protoobp-agent/secrets.yaml — права 600, владелец pobp-agent&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">protoobp_api_key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;ВАШ_API_KEY&amp;gt;&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">postgres_password&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;s3cr3t&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># protoobp.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">file.yaml &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># для JSON-файла — file.json&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">file_path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/etc/protoobp-agent/secrets.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">api_key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[protoobp_api_key]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Идентификатор в &lt;code>ENC[]&lt;/code> — ключ верхнего уровня в файле. Вложенные структуры не поддерживаются. Размер файла ограничен параметром &lt;code>max_file_read_size&lt;/code> в &lt;code>secret_backend_config&lt;/code> (в байтах).&lt;/p>
&lt;h3 id="каталог-с-файлами">Каталог с файлами&lt;/h3>
&lt;p>Каждый секрет хранится в отдельном файле; идентификатор — имя файла относительно каталога. Подходит для секретов, смонтированных в контейнер как файлы.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">secret_backend_type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">file.text&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">secrets_path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/etc/protoobp-agent/secrets&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c"># значение берётся из /etc/protoobp-agent/secrets/postgres_password&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[postgres_password]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ссылки за пределы &lt;code>secrets_path&lt;/code> (например, &lt;code>ENC[../../etc/shadow]&lt;/code>) отклоняются.&lt;/p>
&lt;h3 id="kubernetes-secrets">Kubernetes Secrets&lt;/h3>
&lt;p>Агент читает секреты через API Kubernetes. Идентификатор имеет вид &lt;code>&amp;lt;namespace&amp;gt;/&amp;lt;имя секрета&amp;gt;;&amp;lt;ключ&amp;gt;&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">secret_backend_type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">k8s.secrets&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[monitoring/postgres-credentials;password]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>По умолчанию используются токен сервисного аккаунта пода и адрес API из окружения пода. Переопределить их можно параметрами &lt;code>token_path&lt;/code>, &lt;code>ca_path&lt;/code> и &lt;code>api_server&lt;/code> в &lt;code>secret_backend_config&lt;/code>. Сервисному аккаунту агента нужны права &lt;code>get&lt;/code> на соответствующие объекты &lt;code>Secret&lt;/code> (Role и RoleBinding в пространстве имён секрета).&lt;/p>
&lt;h3 id="hashicorp-vault">HashiCorp Vault&lt;/h3>
&lt;p>Идентификатор задаётся в одном из двух форматов:&lt;/p>
&lt;ul>
&lt;li>&lt;code>&amp;lt;путь к секрету&amp;gt;;&amp;lt;ключ&amp;gt;&lt;/code> — например, &lt;code>ENC[secret/protoobp/postgres;password]&lt;/code>;&lt;/li>
&lt;li>&lt;code>vault://&amp;lt;путь&amp;gt;#&amp;lt;JSON-указатель&amp;gt;&lt;/code> — для вложенных значений, например &lt;code>ENC[vault://secret/protoobp/db#/postgres/password]&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>Версия хранилища KV (v1 или v2) определяется автоматически.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">secret_backend_type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hashicorp.vault&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_address&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://vault.corp.local:8200&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_namespace&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">monitoring &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># для Vault Enterprise, необязательно&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_tls_config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ca_cert&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/etc/protoobp-agent/vault-ca.pem&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_session&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_role_id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">&amp;lt;ROLE_ID&amp;gt; &lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># аутентификация AppRole&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_secret_id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">&amp;lt;SECRET_ID&amp;gt;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Аутентификация&lt;/th>
&lt;th style="text-align:left">Параметры&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">Токен&lt;/td>
&lt;td style="text-align:left">&lt;code>vault_token&lt;/code> в &lt;code>secret_backend_config&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">AppRole&lt;/td>
&lt;td style="text-align:left">&lt;code>vault_session.vault_role_id&lt;/code>, &lt;code>vault_session.vault_secret_id&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">Логин и пароль (userpass)&lt;/td>
&lt;td style="text-align:left">&lt;code>vault_session.vault_username&lt;/code>, &lt;code>vault_session.vault_password&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">LDAP&lt;/td>
&lt;td style="text-align:left">&lt;code>vault_session.vault_ldap_username&lt;/code>, &lt;code>vault_session.vault_ldap_password&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">Kubernetes&lt;/td>
&lt;td style="text-align:left">&lt;code>vault_session.vault_auth_type: kubernetes&lt;/code>, &lt;code>vault_session.vault_kubernetes_role&lt;/code>; при необходимости &lt;code>vault_kubernetes_jwt_path&lt;/code> и &lt;code>vault_kubernetes_mount_path&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Адрес Vault можно также передать стандартной переменной окружения &lt;code>VAULT_ADDR&lt;/code>, она имеет приоритет над &lt;code>vault_address&lt;/code>. Параметры TLS-клиента: &lt;code>ca_cert&lt;/code>, &lt;code>ca_path&lt;/code>, &lt;code>client_cert&lt;/code>, &lt;code>client_key&lt;/code>, &lt;code>tls_server&lt;/code>, &lt;code>insecure&lt;/code> в секции &lt;code>vault_tls_config&lt;/code>.&lt;/p>
&lt;h3 id="другие-типы">Другие типы&lt;/h3>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">&lt;code>secret_backend_type&lt;/code>&lt;/th>
&lt;th style="text-align:left">Источник&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">&lt;code>file.yaml&lt;/code>, &lt;code>file.json&lt;/code>&lt;/td>
&lt;td style="text-align:left">Один файл со словарём секретов&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>file.text&lt;/code>&lt;/td>
&lt;td style="text-align:left">Каталог, один файл на секрет&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>k8s.secrets&lt;/code>&lt;/td>
&lt;td style="text-align:left">Объекты &lt;code>Secret&lt;/code> через API Kubernetes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>k8s.file&lt;/code>&lt;/td>
&lt;td style="text-align:left">Секреты, смонтированные в под как файлы&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>docker.secrets&lt;/code>&lt;/td>
&lt;td style="text-align:left">Секреты Docker Swarm (&lt;code>/run/secrets&lt;/code>)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>hashicorp.vault&lt;/code>&lt;/td>
&lt;td style="text-align:left">HashiCorp Vault&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>akeyless&lt;/code>&lt;/td>
&lt;td style="text-align:left">Akeyless&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>aws.secrets&lt;/code>, &lt;code>aws.ssm&lt;/code>&lt;/td>
&lt;td style="text-align:left">Облачные хранилища секретов AWS&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>azure.keyvault&lt;/code>&lt;/td>
&lt;td style="text-align:left">Azure Key Vault&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>gcp.secretmanager&lt;/code>&lt;/td>
&lt;td style="text-align:left">Google Secret Manager&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="несколько-хранилищ-multi_secret_backends">Несколько хранилищ: multi_secret_backends&lt;/h2>
&lt;p>Каждому хранилищу присваивается имя, которое указывается в ссылке перед точкой с запятой: &lt;code>ENC[&amp;lt;имя хранилища&amp;gt;;&amp;lt;идентификатор&amp;gt;]&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">multi_secret_backends&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">local&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">file.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">file_path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/etc/protoobp-agent/secrets.yaml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hashicorp.vault&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_address&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://vault.corp.local:8200&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">vault_token&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">&amp;lt;VAULT_TOKEN&amp;gt;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">api_key&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[local;protoobp_api_key]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">password&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ENC[vault;secret/protoobp/postgres;password]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ссылка без имени хранилища (&lt;code>ENC[protoobp_api_key]&lt;/code>) при использовании только &lt;code>multi_secret_backends&lt;/code> отклоняется.&lt;/p>
&lt;h2 id="собственная-программа-secret_backend_command">Собственная программа: secret_backend_command&lt;/h2>
&lt;p>Если нужного хранилища нет среди встроенных, укажите путь к собственному исполняемому файлу (скрипт или программа на любом языке):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">secret_backend_command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">/etc/protoobp-agent/fetch-secrets.py&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_arguments&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># необязательно&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">profile&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">monitoring&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_backend_timeout&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">30&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># секунд&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="протокол-обмена">Протокол обмена&lt;/h3>
&lt;p>Агент запускает программу, передаёт ей на стандартный ввод JSON со списком нужных идентификаторов и ждёт ответ на стандартном выводе.&lt;/p>
&lt;p>Запрос:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="nt">&amp;#34;version&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nt">&amp;#34;secrets&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;protoobp_api_key&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;postgres_password&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nt">&amp;#34;secret_backend_timeout&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ответ — объект, где для каждого идентификатора указано значение либо текст ошибки:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;protoobp_api_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="nt">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;ВАШ_API_KEY&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;postgres_password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="nt">&amp;#34;error&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;секрет не найден&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Требования к программе:&lt;/p>
&lt;ul>
&lt;li>проверять старшую часть версии протокола (&lt;code>1&lt;/code>) и завершаться с ошибкой при несовместимой версии;&lt;/li>
&lt;li>уложиться в &lt;code>secret_backend_timeout&lt;/code> секунд;&lt;/li>
&lt;li>выводить не больше &lt;code>secret_backend_output_max_size&lt;/code> байт (по умолчанию 1 МиБ);&lt;/li>
&lt;li>не выводить на стандартный вывод ничего, кроме JSON-ответа; диагностические сообщения писать в stderr.&lt;/li>
&lt;/ul>
&lt;p>Если секрет не получен, параметр сохраняет значение &lt;code>ENC[...]&lt;/code>, а агент пишет ошибку в журнал. Интеграция с таким параметром обычно не сможет подключиться к сервису.&lt;/p>
&lt;p>Минимальный пример на Python, читающий секреты из каталога:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="ch">#!/usr/bin/env python3&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># /etc/protoobp-agent/fetch-secrets.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">json&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">sys&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SECRETS_DIR&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;/etc/protoobp-agent/secrets&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">load&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdin&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">request&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;version&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">startswith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;1.&amp;#34;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;unsupported protocol version: &lt;/span>&lt;span class="si">%s&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">request&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;version&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">handle&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">request&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;secrets&amp;#34;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">path&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">SECRETS_DIR&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">handle&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dirname&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">normpath&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">SECRETS_DIR&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;error&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;invalid handle&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">continue&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;value&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">rstrip&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">except&lt;/span> &lt;span class="ne">OSError&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">handle&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;error&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">)}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">json&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dump&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdout&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Для такой задачи проще использовать встроенный тип &lt;a href="#%d0%ba%d0%b0%d1%82%d0%b0%d0%bb%d0%be%d0%b3-%d1%81-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0%d0%bc%d0%b8">&lt;code>file.text&lt;/code>&lt;/a>; пример показывает формат обмена.&lt;/p>
&lt;h3 id="требования-к-правам-на-файл">Требования к правам на файл&lt;/h3>
&lt;p>Агент отказывается запускать программу, если к ней есть доступ у посторонних пользователей:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Linux&lt;/strong>: файл принадлежит пользователю, от которого работает агент (&lt;code>pobp-agent&lt;/code>), и не имеет прав для группы и остальных:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">chown pobp-agent:pobp-agent /etc/protoobp-agent/fetch-secrets.py
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">chmod &lt;span class="m">700&lt;/span> /etc/protoobp-agent/fetch-secrets.py
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Если программу нужно разделить между несколькими пользователями через группу, включите &lt;code>secret_backend_command_allow_group_exec_perm: true&lt;/code> — тогда группе разрешено чтение и выполнение (&lt;code>chmod 750&lt;/code>), но не запись.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Windows&lt;/strong>: в списке доступа файла могут быть только учётная запись службы агента (по умолчанию &lt;code>pobpagentuser&lt;/code>), группа &lt;code>Administrators&lt;/code> и &lt;code>LOCAL SYSTEM&lt;/code>; явных запретов (Deny) для этих учётных записей быть не должно.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>На встроенный &lt;code>secret-generic-connector&lt;/code> эти требования не распространяются.&lt;/p>
&lt;h3 id="готовый-помощник-для-контейнеров">Готовый помощник для контейнеров&lt;/h3>
&lt;p>В образе агента есть скрипты для чтения секретов, смонтированных в контейнер:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Скрипт&lt;/th>
&lt;th style="text-align:left">Поведение&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">&lt;code>/readsecret.sh &amp;lt;каталог&amp;gt;&lt;/code>&lt;/td>
&lt;td style="text-align:left">Идентификатор — имя файла в указанном каталоге&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>/readsecret_multiple_providers.sh&lt;/code>&lt;/td>
&lt;td style="text-align:left">Идентификатор с префиксом: &lt;code>file@/путь/к/файлу&lt;/code> или &lt;code>k8s_secret@&amp;lt;namespace&amp;gt;/&amp;lt;секрет&amp;gt;/&amp;lt;ключ&amp;gt;&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>В Helm-чарте агента они подключаются параметрами &lt;code>protoobp.secretBackend.command&lt;/code> и &lt;code>protoobp.secretBackend.arguments&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">protoobp&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">secretBackend&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;/readsecret_multiple_providers.sh&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">confd&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">postgres.yaml&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|-&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> instances:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> - host: postgres.db.svc
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> username: protoobp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> password: ENC[k8s_secret@db/postgres-credentials/password]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>При &lt;code>/readsecret_multiple_providers.sh&lt;/code> чарт по умолчанию выдаёт агенту права на чтение секретов во всём кластере (&lt;code>protoobp.secretBackend.enableGlobalPermissions: true&lt;/code>). Чтобы ограничить доступ, отключите этот параметр и выдайте права только на нужные пространства имён, а также используйте &lt;code>secret_allowed_k8s_namespace&lt;/code> или &lt;code>secret_scope_integration_to_their_k8s_namespace&lt;/code> (см. &lt;a href="#%d1%81%d0%bf%d1%80%d0%b0%d0%b2%d0%be%d1%87%d0%bd%d0%b8%d0%ba-%d0%bf%d0%b0%d1%80%d0%b0%d0%bc%d0%b5%d1%82%d1%80%d0%be%d0%b2">справочник&lt;/a>).&lt;/p>
&lt;h2 id="обновление-секретов-без-перезапуска">Обновление секретов без перезапуска&lt;/h2>
&lt;p>По умолчанию секреты запрашиваются один раз при запуске агента. Чтобы ключ API можно было сменить без перезапуска:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">secret_refresh_interval&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">3600&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># секунд; повторно запрашивать ключ API каждый час&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_refresh_scatter&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># случайный сдвиг первого обновления&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">secret_refresh_on_api_key_failure_interval&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">5&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># минут; внеочередное обновление при отказе бэкенда в ключе&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>secret_refresh_interval&lt;/code> — периодическое обновление ключей API; &lt;code>0&lt;/code> отключает.&lt;/li>
&lt;li>&lt;code>secret_refresh_scatter&lt;/code> — первое обновление выполняется в случайный момент интервала, чтобы множество агентов не обращалось к хранилищу одновременно.&lt;/li>
&lt;li>&lt;code>secret_refresh_on_api_key_failure_interval&lt;/code> — если бэкенд отвечает &lt;code>403&lt;/code> или проверка ключа не проходит, агент запрашивает секреты заново, но не чаще одного раза в указанное число минут; &lt;code>0&lt;/code> отключает.&lt;/li>
&lt;/ul>
&lt;p>Обновить секреты вручную: &lt;code>protoobp-agent secret refresh&lt;/code>.&lt;/p>
&lt;h2 id="справочник-параметров">Справочник параметров&lt;/h2>
&lt;p>Все параметры задаются в &lt;code>protoobp.yaml&lt;/code> или переменными окружения с префиксом &lt;code>POBP_&lt;/code> (например, &lt;code>POBP_SECRET_BACKEND_TYPE&lt;/code>). Параметры-объекты (&lt;code>secret_backend_config&lt;/code>, &lt;code>multi_secret_backends&lt;/code>) передаются в переменной окружения как JSON.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Параметр&lt;/th>
&lt;th style="text-align:left">По умолчанию&lt;/th>
&lt;th style="text-align:left">Назначение&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_type&lt;/code>&lt;/td>
&lt;td style="text-align:left">—&lt;/td>
&lt;td style="text-align:left">Тип встроенного хранилища&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_config&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>{}&lt;/code>&lt;/td>
&lt;td style="text-align:left">Параметры встроенного хранилища&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>multi_secret_backends&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>{}&lt;/code>&lt;/td>
&lt;td style="text-align:left">Именованные хранилища&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_command&lt;/code>&lt;/td>
&lt;td style="text-align:left">—&lt;/td>
&lt;td style="text-align:left">Путь к собственной программе&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_arguments&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>[]&lt;/code>&lt;/td>
&lt;td style="text-align:left">Аргументы программы&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_timeout&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>30&lt;/code>&lt;/td>
&lt;td style="text-align:left">Тайм-аут запроса к источнику, секунд&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_output_max_size&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>1048576&lt;/code>&lt;/td>
&lt;td style="text-align:left">Максимальный размер ответа программы, байт&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_remove_trailing_line_break&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>false&lt;/code>&lt;/td>
&lt;td style="text-align:left">Удалять завершающий перевод строки из значений&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_skip_checks&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>false&lt;/code>&lt;/td>
&lt;td style="text-align:left">Не разрешать &lt;code>ENC[]&lt;/code> в конфигурациях интеграций&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_backend_command_allow_group_exec_perm&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>false&lt;/code>&lt;/td>
&lt;td style="text-align:left">Разрешить группе чтение и выполнение программы (Linux)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_refresh_interval&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>0&lt;/code>&lt;/td>
&lt;td style="text-align:left">Период обновления ключей API, секунд&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_refresh_scatter&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>true&lt;/code>&lt;/td>
&lt;td style="text-align:left">Случайный сдвиг первого обновления&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_refresh_on_api_key_failure_interval&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>0&lt;/code>&lt;/td>
&lt;td style="text-align:left">Минимальный интервал внеочередного обновления при отказе в ключе, минут&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_allowed_k8s_namespace&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>[]&lt;/code>&lt;/td>
&lt;td style="text-align:left">Пространства имён, из которых разрешено читать &lt;code>k8s_secret@&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_scope_integration_to_their_k8s_namespace&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>false&lt;/code>&lt;/td>
&lt;td style="text-align:left">Интеграции читают &lt;code>k8s_secret@&lt;/code> только из своего пространства имён&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secret_image_to_handle&lt;/code>&lt;/td>
&lt;td style="text-align:left">&lt;code>{}&lt;/code>&lt;/td>
&lt;td style="text-align:left">Явный список секретов &lt;code>k8s_secret@&lt;/code>, доступных каждому образу&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Три последних параметра взаимоисключающие.&lt;/p>
&lt;h2 id="проверка-и-диагностика">Проверка и диагностика&lt;/h2>
&lt;p>Команда &lt;code>protoobp-agent secret&lt;/code> (в контейнере — &lt;code>agent secret&lt;/code>) показывает:&lt;/p>
&lt;ul>
&lt;li>какой источник секретов используется и права на исполняемый файл;&lt;/li>
&lt;li>каждый идентификатор и места в конфигурации, где он используется.&lt;/li>
&lt;/ul>
&lt;p>Значения секретов команда не выводит. Сводка по секретам также есть в блоке &lt;code>Secrets&lt;/code> вывода &lt;code>protoobp-agent status&lt;/code>.&lt;/p>
&lt;p>Частые ошибки:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th style="text-align:left">Сообщение в журнале&lt;/th>
&lt;th style="text-align:left">Причина&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td style="text-align:left">&lt;code>invalid executable ... 'group' or 'others' have rights on it&lt;/code>&lt;/td>
&lt;td style="text-align:left">Права на программу шире допустимых — см. &lt;a href="#%d1%82%d1%80%d0%b5%d0%b1%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d1%8f-%d0%ba-%d0%bf%d1%80%d0%b0%d0%b2%d0%b0%d0%bc-%d0%bd%d0%b0-%d1%84%d0%b0%d0%b9%d0%bb">требования к правам&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>... returned invalid JSON&lt;/code>&lt;/td>
&lt;td style="text-align:left">Программа выводит в stdout что-то кроме JSON-ответа&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>... takes precedence over ...&lt;/code>&lt;/td>
&lt;td style="text-align:left">Заданы одновременно несколько способов; действует первый по &lt;a href="#%d0%b2%d1%8b%d0%b1%d0%be%d1%80-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1%d0%b0">приоритету&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>secrets path ... is not a directory&lt;/code>&lt;/td>
&lt;td style="text-align:left">Для &lt;code>file.text&lt;/code> в &lt;code>secrets_path&lt;/code> указан не каталог&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td style="text-align:left">&lt;code>invalid secret format, expected 'secret_path;key' ...&lt;/code>&lt;/td>
&lt;td style="text-align:left">Для Vault идентификатор задан без &lt;code>;&amp;lt;ключ&amp;gt;&lt;/code> или &lt;code>#&amp;lt;указатель&amp;gt;&lt;/code>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table></description></item></channel></rss>