API Key
Fystack API key 使用 HMAC secret 或 Ed25519 客户端密钥对来签名请求。本页介绍如何为每种签名方案获取相应的密钥材料。有关签名本身的工作原理,请参阅 API 认证。
除快速测试外,建议优先使用 Client Key Pair(Ed25519)方案。HMAC secret 是你的应用必须持有的明文凭证,而 Ed25519 私钥可以保存在 HSM 或 AWS KMS 中,完全无需可导出,详见下文的客户端密钥对。
HMAC Secret
你无需自行生成密钥。在控制台创建 API key 时如果不注册公钥,Fystack 会为你生成 secret,并以十六进制编码字符串的形式仅显示一次。它比客户端密钥对更易于设置,但该 secret 是你的应用必须持有的明文凭证,条件允许时请优先使用下文的客户端密钥对。
请立即复制 api_secret 并妥善保存,创建后将无法再次获取。如果丢失,请删除该 key 并重新创建。
Using the SDK
import { FystackSDK, Environment } from '@fystack/sdk'
const sdk = new FystackSDK({
credentials: {
apiKey: 'YOUR_API_KEY',
apiSecret: 'YOUR_API_SECRET'
},
workspaceId: 'YOUR_WORKSPACE_ID',
environment: Environment.Production
})
客户端密钥对
使用 Ed25519 方案时,私钥永远不会离开你的进程,在控制台创建 API key 时只需向 Fystack 注册对应的 PEM 公钥。请使用适合你环境的工具生成密钥对,然后将公钥粘贴到控制台中。
在生产环境中,请在 AWS KMS 或本地 HSM 等有硬件支撑的存储中生成密钥,而不是生成 PEM 文件。这样私钥不可导出,永远不会出现在应用内存或磁盘中,即使主机被攻破也无法被窃取。为此请使用下文的 AwsKmsSigner,LocalPrivateKeySigner 和 PEM 文件仅用于本地开发和测试。
使用 SDK
如果你使用 @fystack/sdk,请在 credentials 中传入 signer 而不是原始密钥,它会为你构建规范字符串并签名每个请求。对于进程内的 PEM 密钥使用 LocalPrivateKeySigner,私钥位于 AWS KMS 中时使用 AwsKmsSigner:
Local PEM key
import { FystackSDK, LocalPrivateKeySigner, Environment } from '@fystack/sdk'
const sdk = new FystackSDK({
credentials: {
apiKey: 'YOUR_API_KEY',
signer: new LocalPrivateKeySigner('-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----')
},
workspaceId: 'YOUR_WORKSPACE_ID',
environment: Environment.Production
})
AwsKmsSigner 需要安装 @aws-sdk/client-kms(采用延迟加载),你也可以通过 client 而不是 clientConfig 传入预先配置好的客户端。它的 clientConfig 会直接传给 new KMSClient(...),因此在基于 LocalStack/ministack 的本地开发与生产环境中有所不同:
Local (LocalStack / ministack)
import { FystackSDK, AwsKmsSigner, Environment } from '@fystack/sdk'
const sdk = new FystackSDK({
credentials: {
apiKey: API_KEY,
signer: new AwsKmsSigner({
keyId: 'alias/signer',
clientConfig: {
region: 'ap-southeast-1',
endpoint: 'http://localhost:4566',
credentials: { accessKeyId: 'test', secretAccessKey: 'test' }
}
})
},
environment: Environment.Production,
debug: true
})
Production (AWS)
import { FystackSDK, AwsKmsSigner, Environment } from '@fystack/sdk'
const sdk = new FystackSDK({
credentials: {
apiKey: API_KEY,
// Drop endpoint and credentials, the KMS client picks up the
// task/instance IAM role and the real region automatically.
signer: new AwsKmsSigner({
keyId: 'alias/signer',
clientConfig: { region: 'ap-southeast-1' }
})
},
environment: Environment.Production,
debug: true
})
切勿在生产环境中硬编码 accessKeyId / secretAccessKey,LocalStack 示例中的这对值是仅限本地使用的固定凭证。请改为由运行时的 IAM 角色提供凭证。
不使用 Node.js?请参阅 Ed25519 签名,了解如何在 Go、Python、PHP 和 Java 中使用本地 PEM 密钥或 AWS KMS 直接签名规范字符串。
使用 OpenSSL 生成密钥对
OpenSSL
openssl genpkey -algorithm ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
创建 API key 时将 public.pem 的内容粘贴到控制台中,并保留 private.pem 用于签名,以 new LocalPrivateKeySigner(privateKeyPem) 的形式传给 SDK。
使用 AWS KMS 生成密钥对
AWS KMS 支持将 Ed25519 用作非对称签名密钥(ECC_NIST_EDWARDS25519)。先创建密钥,然后导出公钥部分:
Create the key
KEY_ID=$(awslocal kms create-key \
--key-spec ECC_NIST_EDWARDS25519 --key-usage SIGN_VERIFY \
--query KeyMetadata.KeyId --output text)
echo "$KEY_ID"
get-public-key 返回的已经是 base64 编码的 DER(SubjectPublicKeyInfo),这正是 PEM 公钥所封装的内容,因此无需再通过 openssl 重新格式化。直接用 PEM 头尾包裹 base64 输出即可:
Export as PEM (shortcut)
{
echo "-----BEGIN PUBLIC KEY-----"
awslocal kms get-public-key --key-id alias/signer \
--query PublicKey --output text
echo "-----END PUBLIC KEY-----"
} > pub.pem
Ed25519 公钥只有 32 字节,因此 base64 输出足够短,可以保持在一行内。对于更长的密钥,需要按 64 个字符换行(fold -w 64)才能生成有效的 PEM,Ed25519 密钥则不需要这一步。
另一种等效但更长的方式(先解码为 DER,再由 openssl 重新编码为 PEM)会生成完全相同的文件:
Export as PEM (via openssl)
awslocal kms get-public-key --key-id alias/signer \
--query PublicKey --output text | base64 -d > pub.der
openssl pkey -pubin -inform DER -in pub.der -out pub.pem
无论哪种方式,最终都会得到:
pub.pem
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAKZ0GCR0MBIQGZowZI/1xmWjXlBy09I98JC6Tgn0l0L4=
-----END PUBLIC KEY-----
将其作为该 key 的公钥粘贴到控制台中。私钥保留在 KMS 中,按上文所示使用 new AwsKmsSigner({ keyId: 'alias/signer' }) 签名请求,KMS 永远不会暴露私钥材料。