Claves de API
Las claves de API de Fystack usan un secreto HMAC o un par de claves de cliente Ed25519 para firmar las solicitudes. Esta página explica cómo obtener el material de claves adecuado para cada esquema de firma. Consulta Autenticación de la API para ver cómo funciona la firma en sí.
Prefiere el esquema Client Key Pair (Ed25519) para cualquier uso que vaya más allá de pruebas rápidas. El secreto HMAC es una credencial en texto plano que tu aplicación debe conservar, mientras que una clave privada Ed25519 puede permanecer en un HSM o en AWS KMS sin necesidad de ser exportable, consulta Client Key Pair más abajo.
Secreto HMAC
No necesitas generar ninguna clave. Cuando creas la clave de API desde el panel sin registrar una clave pública, Fystack genera el secreto por ti y lo muestra una sola vez, como una cadena codificada en hexadecimal. Es más simple de configurar que un par de claves de cliente, pero el secreto es una credencial en texto plano que tu aplicación debe conservar, así que prefiere Client Key Pair siempre que puedas.
Copia api_secret de inmediato y guárdalo de forma segura, ya que no se puede recuperar después de la creación. Si lo pierdes, elimina la clave y crea una nueva.
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
})
Par de claves de cliente
Con el esquema Ed25519, la clave privada nunca sale de tu proceso: solo la clave pública PEM correspondiente se registra en Fystack cuando creas la clave de API desde el panel. Genera el par con la herramienta que mejor se adapte a tu entorno y luego pega la clave pública en el panel.
En producción, genera la clave en un almacén respaldado por hardware, como AWS KMS o un HSM local, en lugar de como un archivo PEM. Así la clave privada no es exportable, nunca toca la memoria ni el disco de la aplicación y no puede exfiltrarse aunque el host esté comprometido. Usa AwsKmsSigner (más abajo) para esto, y recurre a LocalPrivateKeySigner y a un archivo PEM solo para desarrollo y pruebas locales.
Usar el SDK
Si usas @fystack/sdk, pasa un signer en credentials en lugar de una clave en bruto: el SDK construye la cadena canónica y firma cada solicitud por ti. Usa LocalPrivateKeySigner para una clave PEM dentro del proceso, o AwsKmsSigner cuando la clave privada reside en AWS KMS:
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 requiere tener instalado @aws-sdk/client-kms (se carga de forma diferida), o bien pasar un cliente preconfigurado mediante client en lugar de clientConfig. Su clientConfig se pasa directamente a new KMSClient(...), por lo que difiere entre el desarrollo local con LocalStack/ministack y producción:
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
})
Nunca codifiques de forma fija accessKeyId / secretAccessKey en producción: ese par del ejemplo de LocalStack es una credencial fija solo para uso local. Deja que el rol IAM del entorno de ejecución proporcione las credenciales.
¿No usas Node.js? Consulta Firma Ed25519 para firmar la cadena canónica directamente, tanto con una clave PEM local como con AWS KMS, en Go, Python, PHP y Java.
Generar un par de claves con OpenSSL
OpenSSL
openssl genpkey -algorithm ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
Pega el contenido de public.pem en el panel al crear la clave de API y conserva private.pem para firmar: pásalo al SDK como new LocalPrivateKeySigner(privateKeyPem).
Generar un par de claves con AWS KMS
AWS KMS admite Ed25519 como clave de firma asimétrica (ECC_NIST_EDWARDS25519). Crea la clave y luego exporta la mitad pública:
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 ya devuelve la clave como DER codificado en base64 (SubjectPublicKeyInfo), que es exactamente lo que envuelve una clave pública PEM, así que no es necesario pasarla por openssl para darle formato. Envuelve directamente la salida base64 con los encabezados PEM:
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
Una clave pública Ed25519 tiene solo 32 bytes, por lo que la salida base64 es lo bastante corta para caber en una sola línea. Con claves más largas tendrías que dividirla en líneas de 64 caracteres (fold -w 64) para producir un PEM válido, pero las claves Ed25519 no necesitan ese paso.
La ruta equivalente, más larga (decodificar a DER y luego dejar que openssl lo vuelva a codificar como PEM), produce un archivo idéntico:
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
En ambos casos obtienes:
pub.pem
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAKZ0GCR0MBIQGZowZI/1xmWjXlBy09I98JC6Tgn0l0L4=
-----END PUBLIC KEY-----
Pega eso en el panel como la clave pública de la clave. La clave privada permanece en KMS: usa new AwsKmsSigner({ keyId: 'alias/signer' }) como se mostró arriba para firmar las solicitudes, y KMS nunca expone el material de la clave privada.