<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>svid | 伪架构师</title>
    <link>/tags/svid/</link>
      <atom:link href="/tags/svid/index.xml" rel="self" type="application/rss+xml" />
    <description>svid</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Thu, 11 May 2017 23:27:37 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>svid</title>
      <link>/tags/svid/</link>
    </image>
    
    <item>
      <title>使用 JWT-SVID 做为访问 Valut 的凭据</title>
      <link>/post/spire-and-vault/</link>
      <pubDate>Thu, 11 May 2017 23:27:37 +0800</pubDate>
      <guid>/post/spire-and-vault/</guid>
      <description>

&lt;p&gt;这次介绍的是在 SPIRE Server 和 Vault Server 之间建立 OIDC 联邦的方法。设置联邦之后，SPIRE 认证的工作负载就能使用 JWT-SVID 来通过 Vault Server 的认证。这样依赖，工作负载就无需使用 &lt;code&gt;AppRole&lt;/code&gt; 或者用户名密码的方式来进行认证了。&lt;/p&gt;

&lt;p&gt;这里解决的就是 0 号海龟问题：如何使用 SPIRE 作为 idP，让应用通过免认证 API 获取自己的身份，以此作为凭据来访问联邦中的 SP 服务&lt;/p&gt;

&lt;p&gt;本文的操作将会涉及以下内容：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;部署 OIDC Discovery Provider Service&lt;/li&gt;
&lt;li&gt;创建一个 DNS A 记录，指向 OIDC Discovery document&lt;/li&gt;
&lt;li&gt;设置一个本地的 Vault Server，用于存储机密&lt;/li&gt;
&lt;li&gt;为 Vault 服务器设置一个 SPIRE Server OIDC Provider 作为认证方法&lt;/li&gt;
&lt;li&gt;使用 SPIRE 身份来访问机密数据&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;开始之前&#34;&gt;开始之前&lt;/h2&gt;

&lt;p&gt;本文内容需要一个公网可以访问的 Kubernetes 以及，并且要开放一个 Ingress 到公网。并且具有一个能够设置 A 记录的域名。另外因为需要暴露 &lt;code&gt;Loadbalancer&lt;/code&gt; 类型的服务，因此最好使用公有云的托管 K8s 进行尝试；并且这里需要使用 Ingress，所以集群里如果没有 Ingress 控制器，还需要部署一个。&lt;/p&gt;

&lt;p&gt;另外需要从 &lt;code&gt;https://github.com/spiffe/spire-tutorials.git&lt;/code&gt; 克隆代码。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;注意：目前（2023-01-16）代码中涉及的部分配置已经过期，请参考 &lt;code&gt;https://github.com/spiffe/spire-tutorials/pull/107&lt;/code&gt; 的内容进行修复。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;根据快速开始章节的指导，准备环境，大致过程如下：&lt;/p&gt;

&lt;p&gt;进入代码的 &lt;code&gt;spire-tutorials/k8s/quickstart&lt;/code&gt; 目录，执行操作。&lt;/p&gt;

&lt;p&gt;首先是启动 SPIRE Server：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;# 创建命名空间
$ kubectl apply -f spire-namespace.yaml
# 创建 SPIRE Server 所需的 ServiceAccount 及其授权
# 创建 Configmap 用于存储 Trust Bundle
$ kubectl apply \
    -f server-account.yaml \
    -f spire-bundle-configmap.yaml \
    -f server-cluster-role.yaml
# 创建 SPIRE Server Configmap
# 创建 SPIRE Server 的 StatefulSet 以及 Service 对象
$ kubectl apply \
    -f server-configmap.yaml \
    -f server-statefulset.yaml \
    -f server-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来启动 SPIRE Agent：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;# 给 Agent 创建 Service Account 并进行授权
$ kubectl apply \
    -f agent-account.yaml \
    -f agent-cluster-role.yaml
# 创建 Agent Configmap，并用 Daemonset 的形式启动 Agent
$ kubectl apply \
    -f agent-configmap.yaml \
    -f agent-daemonset.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;然后是注册工作负载：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;# 创建 Node 注册项，使用 k8s_sat 作为 Selector
$ kubectl exec -n spire spire-server-0 -- \
    /opt/spire/bin/spire-server entry create \
    -spiffeID spiffe://example.org/ns/spire/sa/spire-agent \
    -selector k8s_sat:cluster:demo-cluster \
    -selector k8s_sat:agent_ns:spire \
    -selector k8s_sat:agent_sa:spire-agent \
    -node
# 创建工作负载注册项
$ kubectl exec -n spire spire-server-0 -- \
    /opt/spire/bin/spire-server entry create \
    -spiffeID spiffe://example.org/ns/default/sa/default \
    -parentID spiffe://example.org/ns/spire/sa/spire-agent \
    -selector k8s:ns:default \
    -selector k8s🈂️default
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后是启动工作负载容器：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;# 启动应用
$ kubectl apply -f client-deployment.yaml
...
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;配置-spire-组件&#34;&gt;配置 SPIRE 组件&lt;/h2&gt;

&lt;p&gt;这个案例用到的文件保存在 &lt;code&gt;k8s/oidc-vault/8s&lt;/code&gt; 目录之中，搜索其中的 &lt;code&gt;TODO&lt;/code&gt;，根据本地情况进行修改，涉及内容如下：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;MY_EMAIL_ADDRESS&lt;/code&gt;：涉及文件 &lt;code&gt;oidc-dp-configmap.yaml&lt;/code&gt;。这里需要一个 EMail 地址，这个地址需要满足 Let&amp;rsquo;s Encrypt CA 的要求，用于 OIDC 联邦证书的签署，使用过程中不会向这个邮箱发送邮件。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;MY_DISCOVERY_DOMAIN&lt;/code&gt;：涉及文件包括 &lt;code&gt;ingress.yaml&lt;/code&gt; 、&lt;code&gt;oidc-dp-configmap.yaml&lt;/code&gt; 以及 &lt;code&gt;server-configmap.yaml&lt;/code&gt;。此处需要前面提到的域名，用于定位 OIDC Discovery Document。例如 &lt;code&gt;oidc-discovery.example.org&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;MY_CLUSTER_NAME&lt;/code&gt;：替换为 SPIRE 所在集群的名称，例如 &lt;code&gt;gke_dev-prj_name-central1-c_vault-oidc-tutorial&lt;/code&gt;。涉及文件 &lt;code&gt;server-configmap.yaml&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;上述文件中使用了 &lt;code&gt;example.org&lt;/code&gt; 作为信任域，无需修改。&lt;/p&gt;

&lt;h2 id=&#34;为-oidc-discovery-provider-提供-configmap&#34;&gt;为 OIDC Discovery Provider 提供 Configmap&lt;/h2&gt;

&lt;p&gt;进入目录 &lt;code&gt;k8s/oidc-vault/k8s&lt;/code&gt;，执行下面的命令来更新 SPIRE Server（Quickstart 中已经启动了 Server，这里做一个替换，加入 OIDC Discovery 的服务）：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ kubectl apply \
    -f server-configmap.yaml \
    -f oidc-dp-configmap.yaml \
    -f server-statefulset.yaml
# 验证运行结果
$ kubectl get pods -n spire -l app=spire-server -o \
    jsonpath=&#39;{.items[*].spec.containers[*].name}{&amp;quot;\n&amp;quot;}&#39;
spire-server spire-oidc
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;注意上面提到的 PR，这个 Statefulset 使用的是双容器 Pod，因为启动顺序不可控的问题，需要修改正确的 LivenessProbe 来在合适的时机对 OIDC 相关容器进行重启，才能成功启动 Pod。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;为-oidc-discovery-ip-地址配置-dns&#34;&gt;为 OIDC Discovery IP 地址配置 DNS&lt;/h2&gt;

&lt;p&gt;这里需要使用上文提到的 DNS 记录。下面的步骤会使用这个域名为 Discovery Document 提供端点。Vault Server 会到这里进行查询，完成 Valut Server 和 SPIRE 之间的认证过程。&lt;/p&gt;

&lt;p&gt;实际上还可以使用 &lt;a href=&#34;https://tools.ietf.org/html/rfc7517&#34; target=&#34;_blank&#34;&gt;JWKS&lt;/a&gt; 进行 Vault 的集成认证。这种方式就不需要 DNS 记录了。但是与此相对的，要求 Valut 部署在 Kubernetes 集群之中。相关内容可以参考 &lt;a href=&#34;https://www.vaultproject.io/api-docs/auth/jwt#jwks_url&#34; target=&#34;_blank&#34;&gt;Vault 官方文档&lt;/a&gt;。&lt;/p&gt;

&lt;h3 id=&#34;获取服务-ip-地址&#34;&gt;获取服务 IP 地址&lt;/h3&gt;

&lt;p&gt;前面创建的 &lt;code&gt;spire-oidc&lt;/code&gt; 服务是 &lt;code&gt;Loadbalancer&lt;/code&gt; 类型的服务，因此这里需要获取它的 IP 地址：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ kubectl get service -n spire spire-oidc

NAME           TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)          AGE
spire-oidc     LoadBalancer   10.12.0.18    34.82.139.13   443:30198/TCP    108s
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;创建-dns-记录&#34;&gt;创建 DNS 记录&lt;/h3&gt;

&lt;p&gt;将域名映射到上述地址。然后用 &lt;code&gt;nslookup&lt;/code&gt; 等工具校验域名的有效性。例如：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ nslookup oidc-discovery.example.org
Server:        203.0.113.0
Address:	      203.0.113.0#53

Non-authoritative answer:
Name:	oidc-discovery.example.org
Address: 93.184.216.34
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;可以使用在线工具 &lt;a href=&#34;https://www.whatsmydns.net/&#34; target=&#34;_blank&#34;&gt;DNS Propagation Checker&lt;/a&gt; 来观察 DNS 记录的传播过程。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DNS 生效后，可以在浏览器中访问 &lt;code&gt;https://MY_DISCOVERY_DOMAIN/.well-known/openid-configuration&lt;/code&gt;，顺利的话，会看到如下 JSON 格式的返回内容：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;quot;issuer&amp;quot;: &amp;quot;https://oidc-discovery.example.org&amp;quot;,
  &amp;quot;jwks_uri&amp;quot;: &amp;quot;https://oidc-discovery.example.org/keys&amp;quot;,
  &amp;quot;authorization_endpoint&amp;quot;: &amp;quot;&amp;quot;,
  &amp;quot;response_types_supported&amp;quot;: [
    &amp;quot;id_token&amp;quot;
  ],
  &amp;quot;subject_types_supported&amp;quot;: [],
  &amp;quot;id_token_signing_alg_values_supported&amp;quot;: [
    &amp;quot;RS256&amp;quot;,
    &amp;quot;ES256&amp;quot;,
    &amp;quot;ES384&amp;quot;
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;安装和配置-vault-server&#34;&gt;安装和配置 Vault Server&lt;/h2&gt;

&lt;p&gt;DNS 设置和验证完成之后，开始配置 Vault 服务器。&lt;/p&gt;

&lt;p&gt;在 MacOS 中可以使用 Homebrew 安装 Vault，其它操作系统可以参考&lt;a href=&#34;https://learn.hashicorp.com/tutorials/vault/getting-started-install&#34; target=&#34;_blank&#34;&gt;官方安装文档&lt;/a&gt;。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;建议全新安装 Vault Server，复用已有服务可能会有配置冲突。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;打开一个新的终端窗口，进入源码路径的 &lt;code&gt;./k8s/oidc-vault&lt;/code&gt; 目录。在 &lt;code&gt;./vault/config.jcl&lt;/code&gt; 中加入配置内容，如下配置表示 Vault 监听 &lt;code&gt;127.0.0.1&lt;/code&gt; 的 8200 端口；使用文件作为存储后端；为了测试方便，我们关闭了 TLS，当然，绝不推荐在生产环境中这样使用：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;listener &amp;quot;tcp&amp;quot; {
   address     = &amp;quot;127.0.0.1:8200&amp;quot;,
   tls_disable = 1
}

storage &amp;quot;file&amp;quot; {
   path = &amp;quot;vault-storage&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;用这个配置文件启动 Vault 服务：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault server -config ./vault/config.hcl
...
==&amp;gt; Vault server started! Log data will stream in below:
...
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;初始化-vault-并解封&#34;&gt;初始化 Vault 并解封&lt;/h3&gt;

&lt;p&gt;设置 &lt;code&gt;VAULT_ADDR&lt;/code&gt; 环境变量为 &lt;code&gt;http://127.0.0.1:8200&lt;/code&gt;，然后进行初始化：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault operator init
...
Unseal Key 1: VI0/4yK8H/tHC625aDYaf62+Jmo5qqlizn5bVmsbY0j0
Unseal Key 2: UINTf0oPzpiMIhOU3CNzFpo6Pkun36hGKPlcbQUkl1qT
Unseal Key 3: SYO0yTfCn5IkoQ5f/JzE98yQI8Nfiv51gjXZMamyjXn/
Unseal Key 4: 90vXLQJqba32VpBxYr4jB9gRVu6gRC/uWt812oF44zzP
Unseal Key 5: 2eBBVUC63DOPqNKn4WPoxci4VOfchA7tOr3LTqHtS5FC
Initial Root Token: s.PFuCtYgzjh6mRAfAVjfsGv3O
...
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;建议记录上面的内容（Key 和 Token），后面马上就要用到。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;接下来解封 Vault，需要从上面记录的秘钥中选择任意三个进行解封：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault operator unseal

Unseal Key (will be hidden): &amp;lt;PASTE ONE OF YOUR KEYS HERE&amp;gt;
   
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true # &amp;lt;- 代表是否解封
Total Shares       5
Threshold          3
Unseal Progress    1/3 # &amp;lt;- 解封进度
Unseal Nonce       e1bf3fa2-0058-5703-e2dc-a5c45c1b7f9a
Version            1.3.4
HA Enabled         false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;返回信息中看到了 &lt;code&gt;Sealed: false&lt;/code&gt; 代表解封成功。&lt;/p&gt;

&lt;h3 id=&#34;启用机密引擎并保存一个测试条目&#34;&gt;启用机密引擎并保存一个测试条目&lt;/h3&gt;

&lt;p&gt;使用 CLI 通过跟用户进行访问，启用 &lt;code&gt;kv&lt;/code&gt; 引擎，然后保存数据。&lt;/p&gt;

&lt;p&gt;首先设置环境变量：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ export VAULT_ADDR=http://127.0.0.1:8200
# 使用前面记录的 Token：
$ export VAULT_TOKEN=&amp;quot;s.PFuCtYgzjh6mRAfAVjfsGv3O&amp;quot; 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;启用引擎并保存测试数据：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault secrets enable -path=secret kv
$ vault kv put secret/my-super-secret test=123
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;设置-spire-和-oidc-的联邦关系&#34;&gt;设置 SPIRE 和 OIDC 的联邦关系&lt;/h2&gt;

&lt;p&gt;启用 Vault 的 JWT 认证：&lt;code&gt;vault auth enable jwt&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;设置 OIDC 发现地址：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault write auth/jwt/config \
oidc_discovery_url=https://oidc-discovery.example.org \
default_role=“dev”
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;设置一个 &lt;code&gt;my-dev-policy&lt;/code&gt; 策略，它将会用在后面创建的&lt;code&gt;dev&lt;/code&gt; 角色上。&lt;/p&gt;

&lt;p&gt;进入源码目录的 &lt;code&gt;./k8s/oidc-vault&lt;/code&gt; 目录，在 &lt;code&gt;vault-policy.hcl&lt;/code&gt; 中定义策略，该策略具有读取 &lt;code&gt;/secret/my-super-secret&lt;/code&gt; 的权限：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;path &amp;quot;secret/my-super-secret&amp;quot; {
   capabilities = [&amp;quot;read&amp;quot;]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;然后在 Vault 中加载新建的策略：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault policy write my-dev-policy ./vault/vault-policy.hcl
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;创建 &lt;code&gt;dev&lt;/code&gt; 角色，绑定 JWT 的 &lt;code&gt;subject&lt;/code&gt; 和 &lt;code&gt;audience&lt;/code&gt;，并配置 &lt;code&gt;sub&lt;/code&gt;，声明这个角色会用于认证。有效期设置为 24 小时，这个 Token 会使用 &lt;code&gt;my-dev-policy&lt;/code&gt; 策略：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ vault write auth/jwt/role/dev \
    role_type=jwt user_claim=sub \
    bound_audiences=TESTING \
    bound_subject=spiffe://example.org/ns/default/sa/default token_ttl=24h \
    token_policies=my-dev-policy
...
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;获取-vault-凭据&#34;&gt;获取 Vault 凭据&lt;/h2&gt;

&lt;p&gt;接下来我们来获取用于 Vault 的 Token。这里使用客户端工作负载通过 SPIRE 联邦来获取和进行认证。&lt;/p&gt;

&lt;p&gt;首先获取客户端工作负载的 Pod 名称，例如 &lt;code&gt;client-7c94755d97-mq8dl&lt;/code&gt;。接下来获取客户端的 SVID：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ kubectl exec client-7c94755d97-mq8dl -- /opt/spire/bin/spire-agent api fetch jwt \
   -audience TESTING \
   -socketPath /run/spire/sockets/agent.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;从响应消息中获取 JWT 信息。他应该位于相应信息的 SVID 附近（例如 &lt;code&gt;token(spiffe://xxxxx)&lt;/code&gt;）。是一个长字符串。&lt;/p&gt;

&lt;h2 id=&#34;认证&#34;&gt;认证&lt;/h2&gt;

&lt;p&gt;创建一个 &lt;code&gt;payload.json&lt;/code&gt; 文件，包含如下 JSON 内容，将上个步骤中获得的 Token 替换到文件里：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{&amp;quot;role&amp;quot;: &amp;quot;dev&amp;quot;,&amp;quot;jwt&amp;quot;: &amp;quot;&amp;lt;PASTE_YOUR_JWT_TOKEN_HERE&amp;gt;&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;用这个 Payload 进行认证：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ curl --request POST \
    --data @/path/to/payload.json \
    http://localhost:8200/v1/auth/jwt/login

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;返回信息大概如下格式：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{
   &amp;quot;request_id&amp;quot;: &amp;quot;78bc2546-8e3f-900e-ac32-ae590870ea67&amp;quot;,
   &amp;quot;lease_id&amp;quot;: &amp;quot;&amp;quot;,
   &amp;quot;renewable&amp;quot;: false,
   &amp;quot;lease_duration&amp;quot;: 0,
   &amp;quot;data&amp;quot;: null,
   &amp;quot;wrap_info&amp;quot;: null,
   &amp;quot;warnings&amp;quot;: null,
   &amp;quot;auth&amp;quot;: {
      &amp;quot;client_token&amp;quot;: &amp;quot;s.lQ3KIYjUnFwCJkUnOKKF8kxn&amp;quot;, # &amp;lt;- 客户端 Token
      &amp;quot;accessor&amp;quot;: &amp;quot;ZdVaNVQDcOL15FNSjyWogwiX&amp;quot;,
      &amp;quot;policies&amp;quot;: [
            &amp;quot;default&amp;quot;,
            &amp;quot;my-dev-policy&amp;quot;  # &amp;lt;- 我们创建的策略
      ],
      &amp;quot;token_policies&amp;quot;: [
            &amp;quot;default&amp;quot;,
            &amp;quot;my-dev-policy&amp;quot;
      ],
      &amp;quot;metadata&amp;quot;: {
            &amp;quot;role&amp;quot;: &amp;quot;dev&amp;quot;
      },
      &amp;quot;lease_duration&amp;quot;: 86400,
      &amp;quot;renewable&amp;quot;: true,
      &amp;quot;entity_id&amp;quot;: &amp;quot;5e467f7c-7270-6e2d-2929-e76b9d2b5b32&amp;quot;,
      &amp;quot;token_type&amp;quot;: &amp;quot;service&amp;quot;,
      &amp;quot;orphan&amp;quot;: true
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;测试访问机密数据&#34;&gt;测试访问机密数据&lt;/h2&gt;

&lt;p&gt;接下来用客户端 Token 访问数据：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-command&#34;&gt;$ curl \
     -H &amp;quot;X-Vault-Token: &amp;lt;PASTE_YOUR_client_token_HERE&amp;gt;&amp;quot; \
     http://127.0.0.1:8200/v1/secret/my-super-secret
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;CURL 使用 &lt;code&gt;client_token&lt;/code&gt; 作为凭据，访问 Vault 服务的 REST API。Vault API 会返回下面的 JSON 输出，其中包含我们写入的样本数据：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{
   &amp;quot;request_id&amp;quot;: &amp;quot;1a10d3f7-e3b4-2c05-48c5-94a04f3758bc&amp;quot;,
   &amp;quot;lease_id&amp;quot;: &amp;quot;&amp;quot;,
   &amp;quot;renewable&amp;quot;: false,
   &amp;quot;lease_duration&amp;quot;: 2764800,
   &amp;quot;data&amp;quot;: {
      &amp;quot;test&amp;quot;: &amp;quot;123&amp;quot; # 测试数据
   },
   &amp;quot;wrap_info&amp;quot;: null,
   &amp;quot;warnings&amp;quot;: null,
   &amp;quot;auth&amp;quot;: null
}
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
  </channel>
</rss>
