pantheon-systems/terminus-secrets-manager-plugin

Terminus 的秘密处理插件

1.2.4 2024-05-08 13:18 UTC

README

Pantheon 的 Secrets Manager Terminus 插件是维护行业最佳实践,确保安全构建和应用程序实施的关键。Secrets Manager 提供了一种便捷机制,让您可以直接在 Pantheon 平台上管理您的秘密和 API 密钥。

目录

概述

主要功能

  • 在 Pantheon 上安全托管和维护秘密

  • 通过 Terminus 创建和更新秘密

  • 在集成作曲家构建中使用私有仓库

  • 能够通过 Terminus 命令设置 COMPOSER_AUTH 环境变量和/或 Composer auth.json 认证文件

  • 能够定义秘密的站点和组织所有权

  • 将组织拥有的秘密传播到组织中的所有站点

  • 能够定义每个管理项目的保密程度

  • 秘密在静止状态下加密

早期访问

Secrets Manager 插件可供早期访问参与者使用。Secrets Manager 的功能正在积极开发中。在早期访问期间,Pantheon 的开发团队经常推出新功能。访问 Pantheon Slack 频道(如果您还没有账户,请注册频道)了解如何加入我们的早期访问计划。请参阅 Pantheon 软件评估许可条款 以获取有关访问我们软件的更多信息。

概念

秘密

一个不应向公众公开的键值对,通常像密码、API 密钥或对等加密证书的内容这样的东西。您的站点用于服务页面的 SSL 证书不在此过程的范围之内,并由仪表板在另一个位置管理。有关 SSL 证书的详细信息,请参阅文档。

秘密类型

这是秘密记录中的一个字段。它定义了此秘密的用途以及如何使用它。当前类型包括

  • runtime:此秘密将在应用程序运行时使用对秘密服务的 API 调用来检索。此类型目前在早期访问中尚未使用,但将是设置第三方集成应用程序中 API 密钥等信息的首选方式。

  • env:此秘密将在应用程序运行时设置环境变量。此类型目前在早期访问中尚未使用。

  • composer:此秘密类型用于对私有包进行 composer 认证。

  • file:此类型允许您在秘密中存储文件。此类型目前在早期访问中尚未使用。

请注意,每个密钥只能设置一种类型,并且之后无法更改(除非您删除并重新创建密钥)。

秘密范围

这是密钥记录中的一个字段。它定义了可以访问密钥值的组件。当前的作用域包括:

  • ic:此密钥将由集成作曲运行时读取。您应该使用此作用域来获取对私有存储库的访问权限。

  • web:此密钥将由应用程序运行时读取。

  • user:此密钥将由用户读取。如果您需要在稍后阶段检索密钥值,应设置此作用域。

请注意,您可以针对每个密钥设置多个作用域,但之后无法更改作用域(除非您删除并重新创建密钥)。

所属实体

密钥目前要么属于站点,要么属于组织。在拥有实体内部,密钥可以具有零个或多个环境覆盖。

站点拥有的秘密

这是使用站点 ID 为特定站点设置的密钥。根据类型和作用域,此密钥将在 Pantheon 支持的不同场景中加载。

组织拥有的秘密

这是为组织而非特定站点设置的密钥。此密钥将继承该组织拥有的所有站点的密钥。

注意:由 支持组织 拥有的密钥不会应用于它们支持的站点。只有所有者组织的密钥将适用。

环境覆盖

在某些情况下,当在不同的 Pantheon 环境中访问该密钥时,可能需要为密钥设置不同的值。您可以设置任何现有密钥值的环境覆盖值。

注意:如果密钥不存在,则没有密钥环境可以覆盖,您将收到错误。

秘密的生命周期

当给定运行时(例如集成作曲或环境 php 运行时)为给定站点(和环境)获取密钥时,过程如下:

  • 获取站点密钥(给定类型和作用域)。

  • 根据请求站点环境应用环境覆盖(如果有的话)。

  • 如果站点属于组织

    • 获取组织密钥。

    • 根据请求站点环境应用环境覆盖(如果有的话)。

    • 将组织密钥与站点密钥合并(以下示例将更详细地描述此过程)。

让我们通过一个例子来解释:假设您有一个名为 my-site 的站点,它属于组织 my-org。您还有一个名为 my-other-site 的其他站点,它属于您的个人 Pantheon 账户。

当集成作曲尝试获取 my-other-site 的密钥时,它会这样做:

  • 获取 my-other-site 的作用域 ic 密钥。
  • 应用当前环境的环境覆盖(见下文 注意)。
  • 查看 my-other-site 的所有者。在这种情况下,它不是一个组织,因此没有组织密钥要合并。
  • 处理结果密钥,使其可供作曲使用。

另一方面,当集成作曲尝试获取 my-site 的密钥时,它会这样做:

  • 获取 my-site 的作用域 ic 密钥。
  • 应用当前环境的环境覆盖(见下文 注意)。
  • 查看站点所有者。它确定它是组织 my-org
  • 获取作用域 ic 的组织 my-org 密钥。
  • 将环境覆盖应用于这些密钥以当前环境(见下文 注意)。
  • 以下是一些注意事项,将结果组织密钥与站点密钥合并
    • 站点密钥优先于组织密钥。这意味着将使用站点拥有的密钥 foo 的值,而不是具有相同名称 foo 的组织拥有的密钥的值。
    • 只有所有者组织的密钥将被合并。如果站点有一个支持组织,它将被忽略。
  • 处理结果密钥,使其可供作曲使用。

注意:由于平台设计,集成作曲家的“环境”始终是 dev 或多环境。它永远不会是 testlive。因此,我们不推荐使用环境覆盖来访问作曲家。环境覆盖的主要用途是在您的生活和非生活环境中需要不同的 CMS 键值和环境变量。

插件使用

Secrets Manager 插件要求

秘密管理器需要以下内容

  • Pantheon 账户
  • 使用 集成作曲家 并运行 PHP >= 8.0 的站点
  • Terminus 3.0+

安装

Terminus 3.x 内置插件管理。

运行以下命令安装 Terminus Secrets Manager。

terminus self:plugin:install terminus-secrets-manager-plugin

站点秘密命令

设置秘密

秘密 set 命令的格式如下

  • 名称
  • 类型
  • 一个或多个作用域

运行以下命令在 Terminus 中设置新的秘密

terminus secret:site:set <site> <secret-name> <secret-value>

[notice] Success
terminus secret:site:set <site> file.json "{}" --type=file

[notice] Success
terminus secret:site:set <site> <secret-name> --scope=user,ic

[notice] Success

注意:如果您不包括 typescope 标志,则这些值将设置为默认值(分别为 runtimeuser)。

运行以下命令更新 Terminus 中的现有秘密

terminus secret:site:set <site> <secret-name> <secret-value>

[notice] Success

注意:在更新现有秘密时,不应传递 typescope,因为它们是不可变的。如果您需要更新这些属性,应删除并重新创建秘密。

在 Terminus 中为现有秘密添加或更新环境覆盖

terminus secret:site:set <site>.<env> <secret-name> <secret-value>

[notice] Success

注意:您只能将环境覆盖添加到现有秘密;否则,它将失败。

列出秘密

秘密 list 命令提供可供站点使用的所有秘密的列表。以下字段可用

  • 名称
  • 作用域
  • 类型
  • 环境覆盖值
  • 组织值

请注意,除非在设置秘密时指定了 user 作用域,否则 value 字段将包含占位符值。

运行以下命令列出站点的秘密

terminus secret:site:list <site>

 ------------- ------------- ---------------------------
  Secret name   Secret type   Secret value
 ------------- ------------- ---------------------------
  secret-name   env           secrets-content
 ------------- ------------- ---------------------------
terminus secret:site:list <site> --fields="*"

 ---------------- ------------- ------------------------------------------ --------------- ----------------------------- --------------------
  Secret name      Secret type   Secret value                               Secret scopes   Environment override values   Org values
 ---------------- ------------- ------------------------------------------ --------------- ----------------------------- --------------------
  foo              env           ***                                        web, user
  foo2             runtime       bar2                                       web, user                                     default=barorg
  foo3             env           dummykey                                   web, user       live=sendgrid-live
 ---------------- ------------- ------------------------------------------ --------------- ----------------------------- --------------------

删除秘密

秘密 delete 命令将删除秘密及其所有覆盖。

运行以下命令删除秘密

terminus secret:site:delete <site> <secret-name>

[notice] Success

运行以下命令删除秘密的环境覆盖

terminus secret:site:delete <site>.<env> <secret-name>

[notice] Success

为本地开发生成文件

秘密 local-generate 命令将生成一个用于本地开发模拟秘密的有用的 json 文件。

运行以下命令获取 json 文件

terminus secret:site:local-generate <site> --filepath=./secrets.json
[notice] Secrets file written to: ./secrets.json. Please review this file and adjust accordingly for your local usage.

组织秘密命令

设置秘密

秘密 set 命令的格式如下

  • 名称
  • 类型
  • 一个或多个作用域

运行以下命令在 Terminus 中设置新的秘密

terminus secret:org:set <org> <secret-name> <secret-value>

[notice] Success
terminus secret:org:set <org> file.json "{}" --type=file

[notice] Success
terminus secret:org:set <org> <secret-name> --scope=user,ic

[notice] Success

注意:如果您不包括 typescope 标志,它们的默认值分别是 runtimeuser

运行以下命令更新 Terminus 中的现有秘密

terminus secret:org:set <org> <secret-name> <secret-value>

[notice] Success

注意:在更新现有秘密时,不应传递 typescope,因为它们是不可变的。如果您需要更新这些属性,应删除并重新创建秘密。

在 Terminus 中为现有秘密添加或更新环境覆盖

terminus secret:org:set --env=<env> <org> <secret-name> <secret-value>

[notice] Success

注意:您只能将环境覆盖添加到现有秘密;否则,它将失败。

列出秘密

秘密 list 命令提供可供组织使用的所有秘密的列表。以下字段可用

  • 名称
  • 作用域
  • 类型
  • 环境覆盖值

请注意,除非在设置秘密时指定了 user 作用域,否则 value 字段将包含占位符值。

运行以下命令列出站点的秘密

terminus secret:org:list <org>

 ------------- ------------- ---------------------------
  Secret name   Secret type   Secret value
 ------------- ------------- ---------------------------
  secret-name   env           secrets-content
 ------------- ------------- ---------------------------
terminus secret:org:list <org> --fields="*"

 ---------------- ------------- ------------------------------------------ --------------- -----------------------------
  Secret name      Secret type   Secret value                               Secret scopes   Environment override values
 ---------------- ------------- ------------------------------------------ --------------- -----------------------------
  foo              env           bar                                        web, user
  foo2             runtime       bar2                                       web, user
  foo3             env           dummykey                                   web, user       live=sendgrid-live
 ---------------- ------------- ------------------------------------------ --------------- -----------------------------

删除秘密

秘密 delete 命令将删除秘密及其所有覆盖。

运行以下命令删除秘密

terminus secret:org:delete <org> <secret-name>

[notice] Success

运行以下命令删除秘密的环境覆盖

terminus secret:org:delete --env=<env> <org> <secret-name>

[notice] Success

帮助

运行 terminus list secret 获取完整命令列表。使用 terminus help 获取特定命令的帮助。

速率限制

服务通过 Terminus 支持每个用户每秒最多 3 个请求。如果您达到该限制,API 将返回 429 错误代码,并且插件将引发错误。

PHP SDK 和 pantheon_get_secret() 函数不受此速率限制的影响。

使用集成作曲家中的秘密

您必须配置您的私有仓库并提供一个身份验证令牌,然后才能使用与集成作曲家一起使用的 Secrets Manager Terminus 插件。您可以使用以下任一机制设置此身份验证。

机制 1:Oauth Composer 认证

GitHub 仓库

  1. 生成 Github 令牌。Github 令牌必须选择所有“repo”权限。

    注意:请选择选择所有子框的仓库框。**不要**单独选择所有子框,因为这不会设置正确的权限。

    image

  2. 通过Terminus将密钥值设置为令牌:terminus secret:site:set <site> github-oauth.github.com <github_token> --type=composer --scope=user,ic

  3. 将您的私有仓库添加到composer.json文件的repositories部分。

    {
        "type": "vcs",
        "url": "https://github.com/your-organization/your-repository-name"
    }

    您的仓库应包含一个composer.json文件,其中在name字段中声明了包名。如果它是一个WordPress插件或Drupal模块,它应分别指定为type wordpress-plugindrupal-module。在本指南中,我们将假设您的包名为your-organization/your-package-name

  4. 通过在网站的composer.json文件的require部分添加新条目或使用composer require命令来要求您的私有仓库中定义的包。

    composer require your-organization/your-package-name
  5. 提交您的更改并将它们推送到Pantheon。

GitLab仓库

  1. 生成GitLab令牌。确保为令牌选择read_repository作用域。

  2. 通过Terminus将密钥值设置为令牌:terminus secret:site:set <site> gitlab-oauth.gitlab.com <gitlab_token> --type=composer --scope=user,ic

  3. 将您的私有仓库添加到composer.json文件的repositories部分。

    {
        "type": "vcs",
        "url": "https://gitlab.com/your-group/your-repository-name"
    }

    您的仓库应包含一个composer.json文件,其中在name字段中声明了包名。如果它是一个WordPress插件或Drupal模块,它应分别指定为type wordpress-plugindrupal-module。在本指南中,我们将假设您的包名为your-organization/your-package-name

  4. 通过在网站的composer.json文件的require部分添加新条目或使用composer require命令来要求您的私有仓库中定义的包。

    composer require your-group/your-package-name
  5. 提交您的更改并将它们推送到Pantheon。

Bitbucket仓库

  1. 生成Bitbucket oauth消费者。确保为消费者选择读取仓库权限。同时,将消费者设置为私有,并设置一个(虚拟)回调URL。

  2. 通过Terminus将密钥值设置为消费者信息:terminus secret:site:set <site> bitbucket-oauth.bitbucket.org "<consumer_key> <consumer_secret>" --type=composer --scope=user,ic

  3. 将您的私有仓库添加到composer.json文件的repositories部分。

    {
        "type": "vcs",
        "url": "https://bitbucket.org/your-organization/your-repository-name"
    }

    您的仓库应包含一个composer.json文件,其中在name字段中声明了包名。如果它是一个WordPress插件或Drupal模块,它应分别指定为type wordpress-plugindrupal-module。在本指南中,我们将假设您的包名为your-organization/your-package-name

  4. 通过在网站的composer.json文件的require部分添加新条目或使用composer require命令来要求您的私有仓库中定义的包。

    composer require your-organization/your-package-name
  5. 提交您的更改并将它们推送到Pantheon。

机制 2:HTTP Basic 认证

如果您在多个私有域上有多个私有仓库,您可能需要创建一个COMPOSER_AUTH json并将其通过COMPOSER_AUTH环境变量提供。

Composer能够从环境变量中读取私有仓库访问信息:COMPOSER_AUTH。这些COMPOSER_AUTH变量必须遵循特定的JSON格式

格式示例

#!/bin/bash

read -e COMPOSER_AUTH_JSON <<< {
    "http-basic": {
        "github.com": {
            "username": "my-username1",
            "password": "my-secret-password1"
        },
        "repo.example2.org": {
            "username": "my-username2",
            "password": "my-secret-password2"
        },
        "private.packagist.org": {
            "username": "my-username2",
            "password": "my-secret-password2"
        }
    }
}
EOF

`terminus secret:site:set ${SITE_NAME} COMPOSER_AUTH ${COMPOSER_AUTH_JSON} --type=env --scope=user,ic`

通过 Key 模块在 Drupal 中使用秘密

如果您想在Drupal应用程序中通过Key模块使用Pantheon Secrets,您应使用Pantheon Secrets模块