Saltar al contenido principal

Autenticación de API y tokens JWT

La API de Firma utiliza dos métodos de autenticación: autenticación con clave API para solicitudes de servidor a servidor, y tokens JWT para incrustar los editores de plantillas y de solicitudes de firma en tu aplicación.

Autenticación con clave API

Todos los endpoints de la API requieren autenticación mediante una clave API en el encabezado Authorization.

Cómo funciona

Tu clave API autentica tus solicitudes y determina a qué recursos del espacio de trabajo puedes acceder. Cada espacio de trabajo tiene su propia clave API única, que puedes obtener a través del endpoint Get Workspace. Espacio de trabajo protegido: cada cuenta de empresa tiene un espacio de trabajo protegido que no se puede eliminar. Este espacio de trabajo protegido contiene la clave API principal de tu cuenta, la cual tiene acceso a todos los endpoints de espacios de trabajo, claves API, empresa/cuenta y webhooks. Usa esta clave para operaciones a nivel de cuenta o cuando necesites gestionar varios espacios de trabajo.

Modo de prueba (claves live vs. test)

Cada espacio de trabajo tiene dos claves API: una clave live y una clave test. El modo de prueba se determina según la clave que envíes; no existe un indicador o parámetro independiente.
  • Las solicitudes autenticadas con la clave test no consumen créditos, y cualquier solicitud de firma que creen se marca como de prueba y lleva marca de agua.
  • Las solicitudes autenticadas con la clave live se ejecutan normalmente y consumen créditos.
Ambas claves se devuelven al crear un espacio de trabajo (api_key = live, test_api_key = test) y mediante los endpoints Get Workspace y List Workspaces. Usa la clave test mientras integras y luego cambia a la clave live para producción. Puedes rotar cada tipo de clave de forma independiente: pasa key_type ("live" o "test", por defecto "live") a los endpoints de regenerar y expirar. Rotar un tipo no afecta al otro.
Las claves test son credenciales completas con el mismo alcance de acceso que las claves live; guárdalas en el servidor y nunca las expongas en código de cliente. La única diferencia está en el comportamiento de facturación y marca de agua.

Rotación de claves API

Puedes regenerar claves API para espacios de trabajo no protegidos para mejorar la seguridad. Al regenerar una clave:
  1. Se crea inmediatamente una nueva clave API y se devuelve en la respuesta
  2. Las claves antiguas se marcan para expirar en 24 horas: siguen funcionando durante este periodo de gracia
  3. Puedes expirar manualmente las claves antiguas antes de tiempo una vez que hayas verificado que la nueva clave funciona
Las claves de espacios de trabajo protegidos no se pueden regenerar mediante la API. Esto evita bloqueos accidentales de tu cuenta. Contacta con soporte si necesitas rotar la clave de tu espacio de trabajo protegido.

Regenerar clave API

Genera una nueva clave API para un espacio de trabajo. La clave antigua expirará automáticamente después de 24 horas:
const response = await fetch(
  `https://api.firma.dev/functions/v1/signing-request-api/workspaces/${workspaceId}/api-key/regenerate`,
  {
    method: 'POST',
    headers: {
      'Authorization': process.env.FIRMA_API_KEY,
      'Content-Type': 'application/json'
    }
  }
);

const result = await response.json();
console.log('New API key:', result.new_key);
// Store the new key securely
Respuesta:
{
  "message": "API key regenerated. Old keys will expire in 24 hours.",
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "new_key": "firma_api_abc123xyz...",
  "expiring_keys": [
    {
      "id": "old-key-uuid",
      "expires_at": "2025-12-19T10:30:00Z"
    }
  ]
}

Expirar claves antiguas antes de tiempo

Después de verificar que tu nueva clave funciona, puedes expirar inmediatamente todas las claves pendientes:
const response = await fetch(
  `https://api.firma.dev/functions/v1/signing-request-api/workspaces/${workspaceId}/api-key/expire`,
  {
    method: 'POST',
    headers: {
      'Authorization': process.env.FIRMA_API_KEY,
      'Content-Type': 'application/json'
    }
  }
);

const result = await response.json();
console.log(`Expired ${result.expired_count} key(s)`);
Respuesta:
{
  "message": "Expired 1 pending API key(s)",
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "expired_count": 1,
  "expired_keys": ["old-key-uuid"]
}
Buenas prácticas para la rotación de claves:
  1. Llama al endpoint de regeneración para obtener una nueva clave
  2. Actualiza la configuración de tu aplicación con la nueva clave
  3. Comprueba que la nueva clave funciona correctamente
  4. Llama al endpoint de expiración para invalidar inmediatamente las claves antiguas
  5. Monitorea si hay errores que indiquen que algún servicio todavía usa la clave antigua
Nunca expongas tu clave API en código frontend ni en aplicaciones del lado del cliente. Las claves API solo deben usarse en servicios backend seguros. Guárdalas siempre como variables de entorno.

Formato del encabezado

La clave API se puede enviar de dos formas:
  1. Formato directo (recomendado por su simplicidad):
Authorization: your-api-key-here
  1. Formato Bearer token (opcional):
Authorization: Bearer your-api-key-here
Ambos formatos son válidos. El prefijo Bearer es opcional pero no obligatorio.

Ejemplos de código

curl https://api.firma.dev/functions/v1/signing-request-api/templates \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json"
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/templates',
  {
    headers: {
      'Authorization': process.env.FIRMA_API_KEY,
      'Content-Type': 'application/json'
    }
  }
);

const templates = await response.json();
import os
import requests

headers = {
    'Authorization': os.environ['FIRMA_API_KEY'],
    'Content-Type': 'application/json'
}

response = requests.get(
    'https://api.firma.dev/functions/v1/signing-request-api/templates',
    headers=headers
)

templates = response.json()

Respuesta de error

Si tu clave API falta o es inválida, recibirás una respuesta 401 Unauthorized:
{
  "error": "Unauthorized",
  "code": "UNAUTHORIZED",
  "message": "Invalid or missing API key"
}

Tokens JWT para funciones incrustadas

Los tokens JWT (JSON Web Token) te permiten incrustar el editor de plantillas y el editor de solicitudes de firma de Firma directamente en tu aplicación. Estos tokens están firmados con RSA-256 y tienen un tiempo de vida limitado por seguridad.

Cuándo usar tokens JWT

Usa tokens JWT cuando quieras:
  • Incrustar el editor de plantillas en tu aplicación para que los usuarios creen o editen plantillas de documentos
  • Incrustar el editor de solicitudes de firma para que los usuarios personalicen documentos antes de enviarlos
  • Proporcionar acceso seguro y de tiempo limitado a plantillas o solicitudes de firma específicas
  • Controlar a qué recursos pueden acceder los usuarios sin exponer tu clave API
Los tokens JWT siempre deben generarse desde tu backend seguro, nunca desde código frontend. Tu backend usa la clave API para generar los tokens, que luego se pasan al frontend para inicializar el editor.

Tipos de token JWT

Tipo de tokenEndpointExpiraciónCaso de uso
Token de plantillaGenerate JWT Token for Embedding Templates24 horasIncrustar el editor de plantillas para crear/editar plantillas
Token de solicitud de firmaGenerate JWT Token for Signing Request24 horasIncrustar el editor de solicitudes de firma para personalizar documentos

Flujo de autenticación

Así es como funciona la autenticación JWT para funciones incrustadas:

Guía de implementación

Paso 1: Generar el token JWT (backend)

Genera un token JWT desde tu backend seguro usando tu clave API:
// Backend endpoint to generate JWT for template editing
app.post('/api/get-template-token', async (req, res) => {
  const { templateId } = req.body;

  try {
    const response = await fetch(
      'https://api.firma.dev/functions/v1/signing-request-api/generate-template-token',
      {
        method: 'POST',
        headers: {
          'Authorization': process.env.FIRMA_API_KEY,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          companies_workspaces_templates_id: templateId
        })
      }
    );

    const data = await response.json();
    
    // Return JWT to frontend (never expose API key)
    res.json({ 
      token: data.jwt,
      expiresAt: data.expires_at 
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to generate token' });
  }
});
from flask import Flask, request, jsonify
import os
import requests

app = Flask(__name__)

@app.route('/api/get-template-token', methods=['POST'])
def get_template_token():
    template_id = request.json.get('templateId')
    
    try:
        response = requests.post(
            'https://api.firma.dev/functions/v1/signing-request-api/generate-template-token',
            headers={
                'Authorization': os.environ['FIRMA_API_KEY'],
                'Content-Type': 'application/json'
            },
            json={
                'companies_workspaces_templates_id': template_id
            }
        )
        
        data = response.json()
        
        # Return JWT to frontend (never expose API key)
        return jsonify({
            'token': data['jwt'],
            'expiresAt': data['expires_at']
        })
    except Exception as e:
        return jsonify({'error': 'Failed to generate token'}), 500
Respuesta:
{
  "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "jwt_id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
  "expires_at": "2025-12-18T10:00:00Z",
  "template_id": "template-uuid-here"
}

Paso 2: Inicializar el editor (frontend)

Usa el token JWT para inicializar el editor incrustado en tu frontend:
<!DOCTYPE html>
<html>
<head>
  <title>Template Editor</title>
  <!-- Load the Firma Template Editor library -->
  <script src="https://api.firma.dev/functions/v1/embed-proxy/template-editor.js"></script>
</head>
<body>
  <div id="firma-editor-container" style="width: 100%; height: 600px;"></div>

  <script>
    async function initializeEditor(templateId) {
      // Request JWT from your backend
      const response = await fetch('/api/get-template-token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ templateId })
      });

      const { token, expiresAt } = await response.json();

      // Initialize the embedded editor
      window.FirmaTemplateEditor.init({
        container: '#firma-editor-container',
        jwt: token,
        templateId: templateId,
        theme: 'light', // or 'dark'
        readOnly: false,
        onSave: (savedData) => {
          console.log('Template saved successfully:', savedData);
        },
        onError: (error) => {
          console.error('Editor error:', error);
        },
        onLoad: (template) => {
          console.log('Template loaded:', template);
        }
      });
    }

    // Initialize with your template ID
    initializeEditor('your-template-id-here');
  </script>
</body>
</html>
Para el editor de solicitudes de firma, usa el endpoint JWT de solicitudes de firma y la librería del editor de solicitudes de firma:
// Generate signing request token from backend
const response = await fetch('/api/get-signing-request-token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ signingRequestId })
});

const { token } = await response.json();

// Load signing request editor library
// <script src="https://api.firma.dev/functions/v1/embed-proxy/signing-request-editor.js"></script>

// Initialize signing request editor
window.FirmaSigningRequestEditor.init({
  container: '#firma-signing-request-container',
  jwt: token,
  signingRequestId: signingRequestId,
  theme: 'light',
  onSave: (data) => console.log('Signing request saved:', data),
  onSend: (data) => console.log('Signing request sent:', data),
  onError: (error) => console.error('Error:', error)
});

Paso 3: Revocar el token JWT (opcional)

Revoca un token JWT cuando ya no sea necesario:
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/revoke-template-token',
  {
    method: 'POST',
    headers: {
      'Authorization': process.env.FIRMA_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      jwt_id: 'a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6'
    })
  }
);

const result = await response.json();
// { message: "JWT revoked successfully", jwt_id: "...", revoked_at: "..." }
response = requests.post(
    'https://api.firma.dev/functions/v1/signing-request-api/revoke-template-token',
    headers={
        'Authorization': os.environ['FIRMA_API_KEY'],
        'Content-Type': 'application/json'
    },
    json={
        'jwt_id': 'a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6'
    }
)

result = response.json()

Buenas prácticas de seguridad para JWT

Lista de comprobación de seguridad:
  1. Genera siempre los JWT desde tu backend: nunca expongas tu clave API en código frontend
  2. Usa variables de entorno: guarda las claves API de forma segura, nunca las escribas de forma fija en el código
  3. Valida la expiración del token: comprueba expires_at y renueva los tokens según sea necesario
  4. Usa solo HTTPS: nunca transmitas tokens por conexiones sin cifrar
  5. Revoca los tokens que no uses: revoca los JWT cuando la edición haya terminado o la sesión finalice
  6. Implementa la renovación de tokens: solicita nuevos tokens antes de que expiren para sesiones prolongadas
  7. Limita el alcance de los tokens de forma adecuada: cada JWT está vinculado a una plantilla o solicitud de firma específica


Guías relacionadas

Aprende más sobre cómo implementar funciones incrustadas y trabajar con la API:

Referencia de la API

Endpoints clave de gestión de autenticación y JWT: Gestión de claves API: Gestión de tokens JWT: Primeros pasos: