datasette-secrets 由 datasette 提供

星标

README 源代码

datasette-secrets

PyPI Changelog Tests License

管理用于其他 Datasette 插件的密钥,例如 API 密钥

此插件需要 Datasette 1.0 alpha 版本。

Datasette 插件有时需要访问密钥,例如用于与 Datasette 外部托管的工具集成的 API 密钥 - 如地理编码器或托管的 AI 语言模型。

此插件提供了配置这些密钥的方法

  • 密钥可以使用环境变量进行配置,例如 DATASETTE_SECRETS_OPENAI_API_KEY
  • 密钥可以加密存储在 SQLite 数据库表中,管理员用户可以通过 Datasette Web 界面更新这些密钥

安装

在与 Datasette 相同的环境中安装此插件。

datasette install datasette-secrets

配置

首先,您需要为此插件生成一个加密密钥。运行此命令

datasette secrets generate-encryption-key

将此密钥存储在安全的地方。它将用于加密和解密此插件存储的密钥 - 如果丢失它,您将无法恢复您的密钥。

使用以下两个插件设置配置此插件

plugins:
  datasette-secrets:
    encryption-key:
      $env: DATASETTE_SECRETS_ENCRYPTION_KEY
    database: name_of_database

encryption_key 设置应设置为您之前生成的加密密钥。如果您愿意,可以将其存储在环境变量中。

database 是存储加密密钥的数据库名称。省略此设置以使用内部数据库。

使用内部数据库

虽然存储在 datasette_secrets 表中的密钥是加密的,但我们仍然建议隐藏该表,使其不可见。

一种方法是将该表保存在 Datasette 的内部数据库中,该数据库对所有用户都不可见,即使是已登录的用户也是如此。

默认情况下,内部数据库是一个内存数据库,当 Datasette 重启时会重置。这不利于持久存储密钥!

相反,您应该将 Datasette 切换到使用基于磁盘的内部数据库。您可以通过使用 --internal 选项启动 Datasette 来实现这一点

datasette data.db --internal internal.db

您的密钥将存储在该数据库文件中的 datasette_secrets 表中。

权限

只有拥有 manage-secrets 权限的用户才能通过 Datasette Web 界面管理密钥。

通过将此内容包含在您的 datasette.yml 文件中,您可以将该权限授予 root 用户(或您选择的 ID 用户)

permissions:
  manage-secrets:
    id: root

然后像这样启动 Datasette(使用 --root 获取以 root 用户身份登录的 URL)

datasette data.db --internal internal.db -c datasette.yml --root

或者,使用 -s 选项设置该设置,无需创建配置文件

datasette data.db --internal internal.db \
  -s permissions.manage-secrets.id root \
  --root

使用方法

拥有 manage-secrets 权限的用户将在 Datasette 导航菜单中看到一个新的“管理密钥”链接。此界面也可以通过 /-/secrets 访问。

显示密钥列表的页面将显示最后更新每个密钥的用户。这将使用 actors_from_ids() 机制,如果可用则显示用户的 username,否则显示 name,否则显示 id

对于插件作者

如果插件想要实现密钥功能,可以依赖此插件。

datasette-secrets 添加到 pyproject.toml 文件中的 dependencies 列表中。

然后使用 register_secrets() 插件钩子声明您需要的任何密钥的名称和描述

from datasette import hookimpl
from datasette_secrets import Secret

@hookimpl
def register_secrets():
    return [
        Secret(
            name="OPENAI_API_KEY",
            description="An OpenAI API key"
        ),
    ]

您还可以提供可选的 obtain_urlobtain_label 字段,以链接到用户可以获取 API 密钥的页面

@hookimpl
def register_secrets():
    return [
        Secret(
            name="OPENAI_API_KEY",
            obtain_url="https://platform.openai.com/api-keys",
            obtain_label="Get an OpenAI API key"
        ),
    ]

此钩子可以接受一个可选的 datasette 参数。它可以返回一个列表或一个 async def 函数,该函数在 await 后返回一个列表。

该列表应包含 Secret() 实例,每个实例都有一个名称和可选的描述。描述可以包含 HTML。

要获取密钥的当前值,请使用 await get_secret() 方法

from datasette_secrets import get_secret

# Third argument is the actor_id, optional
secret = await get_secret(datasette, "OPENAI_API_KEY", "root")

如果 Datasette 管理员设置了 DATASETTE_SECRETS_OPENAI_API_KEY 环境变量,则会返回该值。

否则,数据库表中的加密值将被解密并返回 - 如果没有配置密钥,则返回 None

每次访问密钥时,last_used_at 列都会更新。last_used_by 列将设置为传递给 get_secret() 的 actor ID,如果未传递 actor ID,则设置为 null

开发

要在本地设置此插件,首先检出代码。然后创建一个新的虚拟环境

cd datasette-secrets
python3 -m venv venv
source venv/bin/activate

现在安装依赖项和测试依赖项

pip install -e '.[test]'

运行测试

pytest