Hashicorp Vault OSS:用Python hvac库无法登录,但用curl可以登录

后端开发 2026-07-12

我正在使用 hvac Python库来访问我的Vault实例。

这不是Vault Enterprise,而是开源版本(OSS)。

这里是我的Python代码:

VAULT_ADDR="https://vault-oss.eu.gcp.mydomain.net"
VAULT_MOUNT_POINT="mountpoint"
# Random UUID's for the example
VAULT_ROLE_ID="355398f3-76c4-49f6-ac10-c27888b15933" 
VAULT_SECRET_ID="f84cac3d-e34c-4d12-a241-7d0fff706abb" 

client = hvac.Client(
    url=VAULT_ADDR,
    verify=True,
    strict_http=True,
)

client.auth.approle.login(
    role_id=VAULT_ROLE_ID,
    secret_id=VAULT_SECRET_ID,
    mount_point=VAULT_MOUNT_POINT,
)

...

在运行我的程序时,在登录调用处出现错误:

hvac.exceptions.InternalServerError: error performing token check: failed to look up namespace from the token: no namespace, on post https://vault-oss.eu.gcp.mydomain.net/v1/auth/mountpoint/login

但由于我没有使用Enterprise版,问题出在哪里?

另请注意,如果我用有效的Curl请求尝试同一URL,工作正常。

hvac 库上是否需要进行任何设置以达到Vault OSS实例?

同样的代码在EE时,当我按如下方式定义Client时,可以工作:

client = hvac.Client(
    url=VAULT_ADDR,
    verify=True,
    strict_http=True,
    namespace="my-namespace"
)

# and no `mount_point` in the login operation

解决方案

之所以无法工作其实相当棘手。我必须查看源代码才能找到原因。

在源代码的 这个文件 中我发现了以下函数:

def get_token_from_env():
    """Get the token from env var, VAULT_TOKEN. If not set, attempt to get the token from, ~/.vault-token

    :return: The vault token if set, else None
    :rtype: str | None
    """
    token = os.getenv("VAULT_TOKEN")
    if not token:
        token_file_path = os.path.expanduser("~/.vault-token")
        if os.path.exists(token_file_path):
            with open(token_file_path) as f_in:
                token = f_in.read().strip()

...

该行:token_file_path = os.path.expanduser("~/.vault-token") 尝试从位于主目录中的一个文件获取Vault令牌,而在我的情况下,几个月前我曾用Vault EE做过一次旧测试,留下了那个文件,但我记不得自己曾设置过这样的文件。

(我通常从一个专用的文件夹/虚拟环境中执行我的Python脚本(以及其他项目))。

从我的主目录中删除 .vault-token 文件后,登录操作就成功了。

最终代码:

VAULT_ADDR="https://vault-oss.eu.gcp.mydomain.net"
VAULT_MOUNT_POINT="mountpoint"
# Random UUID's for the example
VAULT_ROLE_ID="355398f3-76c4-49f6-ac10-c27888b15933" 
VAULT_SECRET_ID="f84cac3d-e34c-4d12-a241-7d0fff706abb" 


client = hvac.Client(
    url=VAULT_ADDR,
    verify=True,
    strict_http=True,
)

client.auth.approle.login(
    mount_point=VAULT_MOUNT_POINT,
    role_id=VAULT_ROLE_ID,
    secret_id=VAULT_SECRET_ID,
    use_token=True,
)

...

kv_list = client.secrets.kv.v2.list_secrets(
        path=f'{cloud}/mypath/thesystem',
        mount_point=VAULT_MOUNT_POINT
    )

说明:

  • 客户端:为确保TLS已正确启用,在创建Client时需要使用 verify=True,否则TLS验证将被跳过(不适用于生产环境)。官方文档
  • 客户端:某些负载均衡或代理不支持非标准的 "LIST" REST动词,因此可能需要选项 strict_http官方文档
  • 登录:如果你希望在登录后持久化令牌以执行获取密钥操作,请在登录操作中使用选项 use_token=True
  • 通用安全性:当前将role-id和 secret-id设为本地变量,但这只是为了简化问答格式。你应该使用外部配置,例如 dotenv,这样就不会暴露你的秘密。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章