Примечание автора: Все секретные значения открытого текста, показанные в этом руководстве, являются вымышленными. Не пытайтесь использовать их для взлома моих вещей, потому что этих ресурсов не существует.

1Пароль — отличный менеджер паролей, и недавно я начал изучать возможности, которые он может дать для управления секретами, и, черт возьми, это просто! Если ваша команда использует 1Password, вы можете использовать свои хранилища, чтобы делиться секретами и передавать их своим проектам! Ниже приведено руководство, которое я задокументировал, поскольку сам тестировал этот процесс.


Предпосылки

Чтобы следовать этому руководству, вам понадобятся:


Необязательно: создайте хранилище

Пока этот шаг по желанию для завершения обучения рекомендуется организовать свои секреты и учетные данные таким образом, чтобы был разделен доступ. Для этого примера давайте представим, что наш проект выглядит следующим образом:

  • Приложение SaaS на основе JavaScript
  • Инженерная группа:
    • 1 главный инженер
    • 1 старший инженер
    • 1 младший инженер
  • Две среды
    • Non-Prod: доступ есть у всех
    • Производство: Только директор и старший

Учитывая этот контекст, мы хотели бы, чтобы наш младший инженер мог просматривать/добавлять/редактировать непроизводственные секреты, но не производственные. Начнем с создания хранилища, доступного для всех инженеров, и назовем его Новое приложение, не относящееся к продукту:

Описание изображения


Добавить секреты в хранилище

Далее давайте заполним несколько разных учетных данных в этом хранилище. В этом уроке я не буду усложнять и создам два разных предмета. Для нашего первого элемента давайте создадим Новое приложение (локальное). Сюда я бы поместил общие секреты, принадлежащие самому приложению. В этом примере я определил несколько элементов, таких как URL, admin password, postgres connection string, token saltа также JWT Secret:

Описание изображения

Далее давайте добавим второй элемент в наше хранилище для сторонней интеграции. В этом примере мы будем использовать сервис Сумерки и определить наш тест Account SID а также Auth Token который используется приложением при запуске:
Описание изображения


Создайте файл .env-template

В вашем проекте создайте новый файл с именем .env-templateкоторый мы будем использовать в качестве шаблона для создания .env файл, используемый приложением во время выполнения. Давайте создадим наш шаблон, сопоставив переменные среды, которые требуются нашему приложению:

Описание изображения


1Password CLI

Теперь, когда у нас есть наш .env-template создано, давайте сосредоточимся на интерфейсе командной строки 1Password. Во-первых, начните с аутентификация нашего CLI с командой eval $(op signin). Интерфейс командной строки попросит вас подтвердить, с какой учетной записью вы выполняете аутентификацию, и вам будет предложено ввести пароль.

После того, как вы прошли аутентификацию, вам нужно сначала начать с список ваших хранилищ. Чтобы получить список ваших хранилищ, выполните команду op vault list:
Описание изображения

Теперь, когда у нас есть сведения о нашем хранилище, давайте перечислим элементы нашего хранилища. Новое приложение, не относящееся к продукту свод. Чтобы перечислить элементы в хранилище, вы выполните команду op item list --vault <vault name or guid>:
Описание изображения

Наконец, мы скажем CLI получить подробную информацию об элементе в формате JSON, чтобы мы могли скопировать reference указатель на наш шаблон. Вы можете добиться этого с помощью команды op item get <item name or guid> --format json

Ссылочные указатели будут отформатированы как
op://<vault>/<item>/<property> или же op://<vault>/<item>/<section>/<property> в зависимости от того, как вы сохранили секрет в своем элементе. Различные параметры могут быть значениями этого свойства. ярлык/название/имя или же руководство.

example-project % op item get 'NewApp (Local)' --format json
{
  "id": "bzbaer6g2smaqqpntup3zugy3y",
  "title": "NewApp (Local)",
  "version": 1,
  "vault": {
    "id": "54wvogqhltjzolqik3f4cajpru",
    "name": "NewApp Non-Prod"
  },
  "category": "SERVER",
  "last_edited_by": "LFQSVNLW5VCBFDW6QKJRODDWFY",
  "created_at": "2022-09-02T14:50:19Z",
  "updated_at": "2022-09-02T14:50:19Z",
  "sections": [
    {
      "id": "admin_console",
      "label": "Admin Console"
    },
    {
      "id": "n3n3xpw3j5e4e22a6c26kqbuaq",
      "label": "Secrets"
    }
  ],
  "fields": [
    {
      "id": "notesPlain",
      "type": "STRING",
      "purpose": "NOTES",
      "label": "notesPlain",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/notesPlain"
    },
    {
      "id": "url",
      "type": "STRING",
      "label": "URL",
      "value": "
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/URL"
    },
    {
      "id": "admin_console_url",
      "section": {
        "id": "admin_console",
        "label": "Admin Console"
      },
      "type": "STRING",
      "label": "admin console URL",
      "value": "
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Admin Console/admin console URL"
    },
    {
      "id": "admin_console_username",
      "section": {
        "id": "admin_console",
        "label": "Admin Console"
      },
      "type": "STRING",
      "label": "admin console username",
      "value": "admin@newapp.dev",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Admin Console/admin console username"
    },
    {
      "id": "admin_console_password",
      "section": {
        "id": "admin_console",
        "label": "Admin Console"
      },
      "type": "CONCEALED",
      "label": "console password",
      "value": "eZMvXEcKTL9KWRjhyTrN",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Admin Console/console password"
    },
    {
      "id": "izfxzz7i5qbtj7unkkh6nfg3hu",
      "section": {
        "id": "n3n3xpw3j5e4e22a6c26kqbuaq",
        "label": "Secrets"
      },
      "type": "STRING",
      "label": "Postgres Connection String",
      "value": "postgres://postgres:123456@127.0.0.1:5432/dummy",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/Postgres Connection String"
    },
    {
      "id": "6ljbsngcsimhqg7x4iukfbaovm",
      "section": {
        "id": "n3n3xpw3j5e4e22a6c26kqbuaq",
        "label": "Secrets"
      },
      "type": "STRING",
      "label": "Token Salt",
      "value": "07af136084ca0ea0cc192b0769e97122",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/Token Salt"
    },
    {
      "id": "bvbjgzmdo4wwra7noxfnsvvyca",
      "section": {
        "id": "n3n3xpw3j5e4e22a6c26kqbuaq",
        "label": "Secrets"
      },
      "type": "STRING",
      "label": "JWT_Secret",
      "value": "061971eaaaa99212e737c1e789799cd8",
      "reference": "op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/JWT_Secret"
    }
  ]
}
Войти в полноэкранный режим

Выйти из полноэкранного режима


Добавьте указатели ссылок

Скопировав эталонное значение, вернитесь к .env-template файл и вставьте указатель в качестве значения переменной среды. Повторяйте процесс получения эталонных значений до тех пор, пока не .env-template файл завершен. Как мой выглядел после того, как я закончил:

ADMIN_PASSWORD=op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Admin Console/console password
POSTGRES_CONNECTION_STRING=op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/Postgres Connection String
TOKEN_SALT=op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/Token Salt
JWT_SECRET=op://NewApp Non-Prod/bzbaer6g2smaqqpntup3zugy3y/Secrets/JWT_Secret
TWILIO_SID=op://NewApp Non-Prod/Twilio/Test Secrets/Account SID
TWILIO_AUTH_TOKEN=op://NewApp Non-Prod/Twilio/Test Secrets/Auth Token
Войти в полноэкранный режим

Выйти из полноэкранного режима


Введите свои секретные значения

Теперь, когда у нас есть наш .env-template полностью настроен, мы можем запустить команду op inject -i .env-template -o .env который создаст .env файл с секретными значениями. На скриншоте ниже вы можете сравнить шаблон с выводом команды:

Описание изображения


Добавить ярлык проекта

Теперь, когда у вас есть процесс, позволяющий легко создавать .env, давайте упростим использование другими членами команды, написав процесс. Поскольку для этого руководства мы работаем с проектом JavaScript, давайте добавим скрипт в наш package.json файл, поэтому разработчикам нужно только запустить npm run env:generate создавать свои собственные .env файлы локально:

{
  "name": "@mainwaring/example-project",
  "version": "2022.1.0",
  "description": "This is my example project!",
  "main": "index.js",
  "scripts": {
    "env:generate": "eval $(op signin) && op inject -i .env-template -o .env",
    "test": "jest"
  },
  "author": "Joe Mainwaring <joe@mainwaring.dev>",
  "license": "MIT"
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Вы заметите, что в этом примере мой сценарий eval $(op signin) && op inject -i .env-template -o .env и не только op inject -i .env-template -o .env. Объединив команды входа и iject, разработчик сразу же получит signin рабочий процесс, если они еще не прошли проверку подлинности. В противном случае разработчику потребовалось бы выполнить 2-3 дополнительных шага самостоятельно, если его сеанс терминала не прошел проверку подлинности.

Вот и все! Теперь у вас есть команда, использующая общие секреты, управляемые через 1Password! Поделитесь своим опытом с учебником ниже в комментариях.