# HYOK 最佳实践

> 全部文档的索引见 [llms.txt](https://ark.volcengine.com/llms.txt)；在任一文档页面地址后追加 `.md` 可获取该页的 Markdown 版本。

HYOK（Hold Your Own Key）为用户提供了云环境中数据安全的最高级别控制权。该模式允许用户完全掌控密钥的所有权与管理权，并能够通过自有的软件或硬件系统对数据进行加密。在火山方舟平台上，用户可通过“托管外部密钥”功能接入外部密钥，并在执行精调任务时将其指定为数据加密密钥。该密钥将用于加密用户的精调数据等敏感信息，并在任务全生命周期内确保数据加密存储。

<span id="53faf785"></span>
# HYOK核心原理

* **密钥生成**：在用户自有的可信环境（如HSM或可信的KMS）中生成并保存密钥。
* **完全控制**：用户自主管理密钥的全生命周期（创建、存储、轮换、撤销）。火山方舟仅在接受明确授权后执行临时且受控的加解密操作，无法持久持有密钥或访问明文数据。
* **临时访问**：数据密钥绝不会以明文形式传输或存储于火山方舟，仅在必要计算时短暂访问。用户可通过审计日志等方式对访问行为进行验证。

下图是HYOK的原理流程图（以加密存储为例）：

![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/cb501c25f6804fc2bc82374633f1d65e~tplv-goo7wpa0wc-image.image)

需说明以下几点：
1. 火山方舟通过 AssumeRole 机制扮演用户身份以访问其 KMS，该操作需用户授权，且每次调用均会在火山方舟的安全审计页面及火山引擎云审计中记录日志。
2. KMS 在访问外部密钥存储代理（XKS Proxy）时，将使用用户创建外部密钥存储时指定的 CA 证书验证代理身份，以防止中间人攻击。
3. XKS Proxy 会通过用户在创建外部密钥存储时提供的访问密钥（ak/sk，仅用于签名验证）验证请求来源的合法性。
4. 所有数据均经过双重加密，以增强数据机密性。

<span id="5c642407"></span>
# HYOK与传统云加密的区别

|**传统方式** |**HYOK 模式** |
|---|---|
|由CloudKMS管理密钥，平台具备访问用户明文数据的潜在条件。 |用户作为密钥的唯一持有者，从根本上掌控数据访问权限。即使云服务提供商也无法在未经授权的情况下访问明文数据。 |

<span id="4ffb4283"></span>
# HYOK典型应用场景

* **隐私保护**：精调数据中包含高度敏感信息，如个人身份信息（PII）、财务数据或商业机密。
* **合规要求**：需符合数据主权法规，要求数据或密钥不得超出特定地域或组织边界。
* **自主可控**：用户已具备外部KMS或CloudHSM等密钥管理基础设施，希望延续现有控制策略。

<span id="02aeefc5"></span>
# XKS Proxy功能

火山方舟目前提供基础版本的XKS Proxy供用户参考和使用。后续将开放相关接入协议，用户可基于协议自行实现代理服务，并接入其他KMS或CloudHSM系统。
基础版XKS Proxy功能：

|密钥来源 |aliyun/aws |
|---|---|
|加密算法 |AES_256 |

<span id="25cdaa94"></span>
# HYOK使用流程

![](https://arkdocs.tos-cn-beijing.volces.com/flowcharts/resources/hyok-best-practices-01.svg)

> **说明**
>
> 本节将介绍如何通过VPC终端节点服务托管外部密钥至外部密钥存储。其中，第1至4步为创建外部密钥存储所需的前置资源准备（本文以火山引擎资源为例）。**如果您已具备相应资源，可跳过相关步骤**。第5至9步为在火山方舟平台上创建外部密钥存储并托管外部密钥的具体操作指引。

<span id="a2ba7db5"></span>
## 1.创建VPC

VPC 终端节点服务需与外部密钥管理器所在 VPC 连接。您可使用符合外部密钥存储要求的现有 VPC；如无可用 VPC，请参照下图于 [火山引擎-私有网络](https://console.volcengine.com/vpc/region:vpc+cn-beijing/vpc?) 中创建。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/1392eb6504b54191ad9995112a36916e~tplv-goo7wpa0wc-image.image)</div>

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/d1647ec2cdd14e35a39009dd94867997~tplv-goo7wpa0wc-image.image)</div>

<span id="e2724657"></span>
## 2.创建ECS

在创建所需的VPC终端节点服务前，您需要有一台可部署XKS Proxy的ECS实例。下图为在 [火山引擎-云服务器](https://console.volcengine.com/ecs/region:ecs+cn-beijing/instance?) 创建ECS实例的示例

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/97af06c677e24bf793c18cbe6431d712~tplv-goo7wpa0wc-image.image)</div>

* 基础配置：**地域及可用区**需要与**步骤1**中所创建的 VPC 保持一致

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/3f89b901e9b64cd8a3ae50b38d5afb2f~tplv-goo7wpa0wc-image.image)</div>

* 网络配置：选择**步骤1**中创建的 VPC 和子网，并绑定公网 IP（新建或使用已有）

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/4122c2edec7d4475bef83f8531f4375f~tplv-goo7wpa0wc-image.image)</div>

* 自定义配置：配置 SSH 密钥或密码作为登录凭证

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/c2c1f663639f452db5f3d6f01fabb4b6~tplv-goo7wpa0wc-image.image)</div>

* 确认订单：阅读并同意《云服务器服务条款》后完成创建。

<span id="45e6409a"></span>
## **3.创建CLB并关联至指定VPC**

CLB 用于将火山引擎 KMS 的访问流量路由至XKS Proxy。
您可根据下图指引在 [火山引擎-传统型负载均衡](https://console.volcengine.com/clb/region:clb+cn-beijing/LoadBalancer?) 中创建CLB并配置监听端口：
* 点击**实例管理-创建负载均衡**进行配置，选择**步骤1**中创建的VPC和子网

![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/16cd873a1a464b108807744207a4cb02~tplv-goo7wpa0wc-image.image)

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/86f46d5fb5f3423ab1805572cfc48e53~tplv-goo7wpa0wc-image.image)</div>

* 添加监听器：在**实例管理界面**，选择上一步创建的负载均衡，配置监听器

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/45710b6c13704c6ab275340e3026377c~tplv-goo7wpa0wc-image.image)</div>

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/ea16912ac094445ca12804db02167032~tplv-goo7wpa0wc-image.image)</div>

* **后端服务器组**：挂载**步骤2**中创建的 ECS 实例

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/14607d10124347bf917874cc24e1f075~tplv-goo7wpa0wc-image.image)</div>

* **添加后端服务器**：选择具备公网访问能力的 ECS，确保负载均衡端口与服务器端口一致

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/322d7ec003414cc0a3825a350b4ddb65~tplv-goo7wpa0wc-image.image)</div>

* **健康检查**：启用健康检查功能

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/07206a09e6fd4614ad7a67e2d85af1e6~tplv-goo7wpa0wc-image.image)</div>

> **说明**
>
> 具体配置请根据实际需要确定。若仅用于方舟托管外部密钥，建议选用基础规格即可。

<span id="cd434f82"></span>
## **4.创建VPC终端节点服务**

* 完成前述资源准备后，即可创建 [VPC终端节点服务](https://console.volcengine.com/pl/region:pl+cn-beijing/endpointServices?)。

    * **服务资源**需选择**步骤3**中创建的负载均衡。

    * **在高级配置中，** 请勾选“自动接受连接”。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/1e1e1a9a79af41cc8cc53aad8720fac8~tplv-goo7wpa0wc-image.image)</div>

* 创建完成后，请在**终端节点服务列表页**中记录**服务域名**，该信息将在后续创建托管外部密钥时使用。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/6a9dae3b2e144791965c9a89ce89d957~tplv-goo7wpa0wc-image.image)</div>

<span id="38ab96bb"></span>
## **5.配置终端节点服务白名单**

* 点击已创建的终端节点服务，选择**服务白名单**，点击**添加服务白名单**，输入KMS服务账号 `2100052433`。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/4bc3306a8c374ae084f23ac9a5134662~tplv-goo7wpa0wc-image.image)</div>

<span id="bab434c9"></span>
## 6.XKS Proxy 部署

请返回至**步骤2**中已创建的 ECS 实例，部署 XKS Proxy 并手动配置鉴权信息，包括：外部 KMS 的 ak/sk、用于验证火山引擎 KMS 身份的 ak/sk、保障连接安全的 CA 证书等元数据。
您可通过 SSH 或控制台连接到ECS 实例，并按下图指引完成 XKS Proxy 部署（本文以控制台连接为例）：

![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/d2aeab982d4149c1837968f1c14d1318~tplv-goo7wpa0wc-image.image)

* **连接 ECS 实例**：若需其他连接方式，请参见 [相关操作指南](https://docs.volcengine.com/docs/6396/81032?lang=zh)。
* **获取 XKS Proxy**：

    * 下载 XKS Proxy 压缩包。

```Plain Text
# 下载压缩包
wget https://ark-public-cn-beijing.tos-cn-beijing.volces.com/xksproxy/xksproxy.tar.gz
# 解压xksproxy压缩包
tar -zxvf xksproxy.tar.gz
# 进入解压的文件夹
cd xksproxy
```

* 其主要目录结构如下：

    ```Plain Text
    xksproxy/
    ├── conf
    │   └── config.yaml # 配置文件
    ├── scripts
    │   ├── README.md # CA/服务端证书生成指南
    │   ├── ca.cnf
    │   ├── cert_gen.sh
    │   ├── generate_ca.sh
    │   ├── generate_server_cert.sh
    │   └── server.cnf
    └── xksproxy # 主程序
    ```

* **证书配置**：

    * 若您已持有 CA 或服务端证书，请将其保存至指定目录并在 `config.yaml` 中配置路径。

    * 若无相应证书或仅需功能体验，可参照 `scripts/``README.md` 文档创建。

    ```Plain Text
    # 1.记录上述Step4「创建VPC终端节点服务」步骤中的服务域名
    # 假设域名为epsvc-xxx.cn-beijing.privatelink.volces.com

    # 2.打开scripts目录
    cd xksproxy/scripts

    # 3.生成根证书和服务端证书
    ./cert_gen.sh all --dns "*.epsvc-xxx.cn-beijing.privatelink.volces.com" --output /path/to/cert/dir
    ```

    * 生成后的证书目录结构如下：

    ```Plain Text
    certs
    ├── ca.key        # 私有CA私钥
    ├── ca.pem        # 私有CA证书
    ├── ca.srl        # 私有CA序列号
    ├── cert.csr      # 服务端证书签名请求
    ├── cert.pem      # 服务端证书
    ├── key.pem       # 服务端私钥
    └── openssl.cnf   # 服务端证书配置
    ```

* **编辑配置文件**：进入 `conf` 目录，编辑 `config.yaml` 文件。

```Plain Text
# cd conf
server:
  host: "0.0.0.0"
  port: 443
  read_timeout: 30
  write_timeout: 30
  path_prefix: ""               # 路径前缀（选填）
  tls:
    enabled: true               # 是否开启tls（目前必须开启）
    cert_path: ""               # 服务端证书路径（必填）
    key_path: ""                # 服务端密钥路径（必填）
    ca_path: ""                 # CA证书路径（必填）
    ca_base64: ""               # CA证书der格式base64编码 (启动服务时自动填充)

# SignV4 authentication configuration
auth:
  access_key_id: "<YOUR_ACCESS_KEY_ID>"         # 认证ak（留空则启动自动填充）
  secret_access_key: "<YOUR_SECRET_ACCESS_KEY>" # 认证sk（留空则启动自动填充）

kms:
  - id: "local-kms"                        # 外部kms唯一标识
    provider: "local"                      # 根据kms服务商填写，目前支持aliyun、aws和local（本地调试模式）
    region: ""                             # kms region
    endpoint: ""                           # kms服务endpoint
    access_key: ""                         # kms服务鉴权ak
    secret_key: ""                         # kms服务鉴权sk
    key_mapping:                           # 密钥映射
      "external-key-1": "real-key-id-1"    # key为xksproxy中该密钥别称，value为kms服务真实密钥id

log:
  level: "info"
  file_path: ""
  max_size: 100
  max_age: 7
  max_backups: 5

# XKS proxy configuration
xks_proxy:                                # xksproxy版本信息，保持不变即可
  fleet_size: 1
  vendor: "Volc XKS Proxy"
  model: "Volc XKS Proxy v1.0"
```

|**字段** |**描述** |**示例** |是否必填 |
|---|---|---|---|
|server.path_prefix |路径前缀 |myxks |否 |
|server.tls.cert_path |服务端证书路径 |/root/cert.pem |是 |
|server.tls.key_path |服务端密钥路径 |/root/key.pem |是 |
|server.tls.ca_path |CA证书路径 |/root/ca.pem |是 |
|server.tls.ca_base64 |CA证书der格式base64编码 |/ |否（启动时自动填充） |
|auth.access_key_id |用于验证kms侧身份的ak，kms会使用该ak/sk做请求签名 | XT7II5R7F4OORP5Z4PRB |否（留空则自动填充） |
|auth.secret_access_key |用于验证kms侧身份的ak，kms会使用该ak/sk做请求签名 |hHnacnaJEUa0AlYd6WZXUlPg9QG0Gzasrfjd4VkWIpp |否（留空则自动填充） |
|kms.id |用于唯一标识外部kms |mykms |是 |
|kms.provider |kms的提供方，目前支持： |local |是 | \
| | | | | \
| |* aliyun：阿里云kms | | | \
| |* aws：aws kms | | | \
| |* local：本地调试模式，加解密发生在本地（不可用于生产环境） | | |
|log.level |日志级别 |error |否 | \
| | | | | \
| |* debug | | | \
| |* info | | | \
| |* warn | | | \
| |* error | | |
|log.file_path |日志存储位置 |/mypath/xksproxy.log |否 |
|log.max_size |日志最大容量（MB） |100 |否（默认100MB） |
|log.max_age |日志最大存储时间（天） |7 |否（默认7天） |
|log.max_backups |日志最大存储数量 |100 |否（默认5个） |
|xks_proxy.* |xksproxy的版本元信息 |/ |否 |

* **启动代理**：执行启动命令，运行 XKS Proxy。**仅当成功启动后，方可连接至外部密钥存储**。

    ```Plain Text
    ./xksproxy server
    ```

<span id="3152fa86"></span>
## 7.开通并授权火山引擎 KMS 服务

您需手动开通 KMS 服务并授予火山方舟相应访问权限，以便其代理您完成外部密钥的托管。
* 进入 [火山引擎 KMS 控制台](https://console.volcengine.com/kms/region:kms+cn-beijing/primary?)，开通服务。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/78d4c617d7c041a79185ca864c37982f~tplv-goo7wpa0wc-image.image)</div>

* 前往 [访问控制授权页面](https://console.volcengine.com/iam/service/attach_role/?ServiceName=kms)。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/f7218891bf4e46578c42b48b2b1a55cb~tplv-goo7wpa0wc-image.image)</div>

* 查看权限内容并完成授权。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/51152e10b17a4d17ae2b9c2773dc0b68~tplv-goo7wpa0wc-image.image)</div>

<span id="73bf3ab9"></span>
## 8.创建外部密钥存储

在火山方舟控制台中，选择对应的 VPC 终端节点服务，并配置代理连接信息。所需配置内容请参照**步骤6**中 `config.yaml` 文件的相应条目。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/71ce6d31cf6742bfa20ebac8a59be16d~tplv-goo7wpa0wc-image.image)</div>

<span id="eafe0cc0"></span>
## 9.托管外部密钥

托管外部密钥将由方舟代理您在火山引擎 KMS 中创建一款用户主密钥。请选择**步骤8**中创建的外部密钥存储，并可按需自定义密钥环与密钥信息。

<div style="text-align: center">![](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/add5ecef640c4672921249f53e828db0~tplv-goo7wpa0wc-image.image)</div>

<span id="c68b8ceb"></span>
# 常见问题

**Q：可以使用其他厂商的KMS服务接入方舟的托管外部密钥功能吗？**
**A**：可以，您使用的其他厂商KMS服务的ak/sk需具备以下权限：`kms:Encrypt`、`kms:Decrypt` 和 `kms:DescribeKey`。
**Q：如果我已经拥有相关的云服务资源，是否还需要重新创建？**
**A**：如果您已拥有相应的云服务资源（如ECS、CLB），并确保其与目标资源处于同一可用区且能正常访问外部密钥存储，则可以跳过相关创建步骤。
**Q：XKS Proxy 无法连接到外部密钥存储应如何排查？**
**A**：请按以下步骤依次检查：

1. 确认终端节点服务是否已开启“自动接受连接”选项；

2. 检查是否已完成对火山引擎KMS服务的授权；

3. 验证XKS Proxy是否已正确部署并运行。

**Q：如果密钥已被删除，为何精调任务仍在进行？**
**A**：精调任务仅在加密数据的输出和访问时需要访问密钥。若该阶段已完成，精调任务进程将不受密钥删除影响；若任务仍在进行且需访问加密数据，则会因密钥不可用而提示错误信息。
**Q：使用托管外部密钥是否会带来时延性能的损失？**
**A**：该功能的时延取决于火山引擎KMS、XKS Proxy及外部密钥存储接口的延时和网络情况。与直接使用火山引擎KMS相比，会有百毫秒级别的延迟差距，但不会对精调任务的整体性能产生影响。
