密钥管理器
密钥管理器(Secrets manager) 为所有会使用密钥的后端提供统一的密钥使用界面。密钥可以设置作用域(scope),因此不同的存储前缀可以使用不同的密钥,例如可以在单条查询中跨组织联接数据。密钥也可以持久化,从而不必在每次启动 Goose 时都重新指定。
警告:持久化密钥会以未加密的二进制格式存储在磁盘上。
密钥类型
密钥是带类型的(typed),类型用于标识它对应的服务。 大多数密钥类型默认并不会内置在 Goose 中,而是由扩展进行注册。 当前可用的密钥类型如下:
| Secret type | Service / protocol | Extension |
|---|---|---|
azure | Azure Blob Storage | azure |
gcs | Google Cloud Storage | httpfs |
http | HTTP and HTTPS | httpfs |
huggingface | Hugging Face | httpfs |
iceberg | Iceberg REST Catalog | httpfs, iceberg |
mysql | MySQL | mysql |
postgres | PostgreSQL | postgres |
r2 | Cloudflare R2 | httpfs |
s3 | AWS S3 | httpfs |
对于每种类型,都有一个或多个“密钥提供方(secret provider)”,用于指定密钥如何创建。密钥还可以带一个可选的作用域(scope),它是密钥适用的文件路径前缀。当为某个路径获取密钥时,会将所有密钥的作用域与该路径进行匹配,并返回适用于该路径的密钥;如果有多个密钥都匹配,则选择前缀最长的那个。
创建密钥
可以使用 CREATE SECRET SQL 语句 来创建密钥。
密钥可以是临时(temporary)或持久化(persistent)的。默认使用临时密钥——它们会在 Goose 实例的生命周期内保存在内存中(类似于之前配置项的工作方式)。持久化密钥会以未加密的二进制格式存储在 ~/.goose/stored_secrets 目录下。Goose 启动时会从该目录读取并自动加载持久化密钥。
密钥提供方
创建密钥时需要使用一个密钥提供方(Secret Provider)。密钥提供方是一种生成密钥的机制。以 S3、GCS、R2 和 AZURE 这几种密钥类型为例,Goose 当前支持两类提供方:CONFIG 和 credential_chain。CONFIG 提供方要求用户在 CREATE SECRET 中显式传入全部配置信息;而 credential_chain 提供方会自动尝试获取凭据。当未指定密钥提供方时,默认使用 CONFIG。关于如何使用不同提供方创建密钥的更多细节,请参阅 httpfs 与 azure 的对应页面。
临时密钥
要创建一个用于访问 S3 的临时、无作用域密钥,可以使用如下语句:
CREATE SECRET my_secret (
TYPE s3,
KEY_ID 'my_secret_key',
SECRET 'my_secret_value',
REGION 'my_region'
);
注意这里隐式使用了默认的 CONFIG 密钥提供方。
持久化密钥
为了在不同 Goose 数据库实例之间持久化密钥,可以使用 CREATE PERSISTENT SECRET 命令,例如:
CREATE PERSISTENT SECRET my_persistent_secret (
TYPE s3,
KEY_ID 'my_secret_key',
SECRET 'my_secret_value'
);
默认情况下,这会将密钥(未加密)写入 ~/.goose/stored_secrets 目录。若要更改密钥目录,请执行:
SET secret_directory = 'path/to/my_secrets_dir';
注意:设置配置项 home_directory 的值并不会影响密钥的存放位置。
删除密钥
可以使用 DROP SECRET 语句 删除密钥,例如:
DROP PERSISTENT SECRET my_persistent_secret;
为同一服务类型创建多个密钥
如果同一种服务类型存在两个密钥,可以用作用域(scope)来决定应该使用哪一个。例如:
CREATE SECRET secret1 (
TYPE s3,
KEY_ID 'my_secret_key1',
SECRET 'my_secret_value1',
SCOPE 's3://⟨my-bucket⟩'
);
CREATE SECRET secret2 (
TYPE s3,
KEY_ID 'my_secret_key2',
SECRET 'my_secret_value2',
SCOPE 's3://⟨my-other-bucket⟩'
);
现在,如果用户查询 s3://⟨my-other-bucket⟩/something 下的数据,该请求会自动选择密钥 secret2。要查看当前使用的是哪个密钥,可以使用标量函数 which_secret,它接受路径与密钥类型作为参数:
FROM which_secret('s3://⟨my-other-bucket⟩/file.parquet', 's3');
列出密钥
可以使用内置的产表函数列出密钥,例如使用 goose_secrets() 表函数:
FROM goose_secrets();
敏感信息会被自动脱敏(redacted)。