Licencias en Cualquier Lenguaje
La API de Auris Licensing es una API REST/JSON estándar. No necesitas un SDK — cualquier lenguaje que pueda hacer un POST HTTP y parsear JSON puede validar licencias, activar dispositivos y controlar funcionalidades.
Si estás usando JavaScript/TypeScript, usa el SDK @auris/js en su lugar — gestiona automáticamente el fallback offline y el caché de revocaciones.
El Único Endpoint Que Necesitas
POST https://your-auris-domain/api/licensing/validate
// Request
{
"key": "VIG-A8BC-D3EF-G4HJ-K5LM"
}
// Response (valid)
{
"valid": true,
"features": ["threat-intel", "vuln-scan"],
"seats": { "used": 1, "max": 5 },
"expiresAt": "2027-03-15T00:00:00Z"
}
// Response (invalid)
{
"valid": false,
"reason": "EXPIRED"
}Encabezados: Content-Type: application/json y x-tenant: your-tenant (opcional, por defecto altovar).
No se necesita Bearer token. Este es un endpoint público.
Ejemplos por Lenguaje
C#
C# (.NET)
using System.Net.Http;
using System.Text;
using System.Text.Json;
public record LicenseResult(bool Valid, string? Reason, string[]? Features, DateTime? ExpiresAt);
public class AurisLicense
{
private static readonly HttpClient _http = new();
private readonly string _baseUrl;
private readonly string _tenant;
public AurisLicense(string domain, string tenant = "altovar")
{
_baseUrl = $"https://{domain}";
_tenant = tenant;
}
public async Task<LicenseResult> ValidateAsync(string key)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/validate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
var response = await _http.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<LicenseResult>(json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
}
public async Task ActivateAsync(string key, string fingerprint, string? name = null)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/activate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key, fingerprint, name }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
var response = await _http.SendAsync(request);
if (!response.IsSuccessStatusCode)
throw new Exception($"Activation failed: {response.StatusCode}");
}
public async Task DeactivateAsync(string key, string fingerprint)
{
var request = new HttpRequestMessage(HttpMethod.Post, $"{_baseUrl}/api/licensing/deactivate")
{
Content = new StringContent(
JsonSerializer.Serialize(new { key, fingerprint }),
Encoding.UTF8, "application/json")
};
request.Headers.Add("x-tenant", _tenant);
await _http.SendAsync(request);
}
}Uso:
var license = new AurisLicense("auth.yourdomain.com");
// Validate
var result = await license.ValidateAsync("VIG-A8BC-D3EF-G4HJ-K5LM");
if (result.Valid)
{
Console.WriteLine($"Valid! Features: {string.Join(", ", result.Features ?? [])}");
}
// Activate device
await license.ActivateAsync("VIG-A8BC-D3EF-G4HJ-K5LM", GetMachineId(), Environment.MachineName);
// Feature gating
if (result.Features?.Contains("threat-intel") == true)
{
// Enable threat intel module
}curl
Para pruebas o scripts de shell:
# Validate
curl -s -X POST https://auth.yourdomain.com/api/licensing/validate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM"}' | jq
# Activate device
curl -s -X POST https://auth.yourdomain.com/api/licensing/activate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM", "fingerprint": "abc123", "name": "Dev Machine"}'
# Deactivate device
curl -s -X POST https://auth.yourdomain.com/api/licensing/deactivate \
-H "Content-Type: application/json" \
-H "x-tenant: altovar" \
-d '{"key": "VIG-A8BC-D3EF-G4HJ-K5LM", "fingerprint": "abc123"}'Validación Offline (JWT)
Cuando se emite una clave, viene acompañada de un jwtToken — un JWT firmado que contiene los derechos. Para validación offline sin SDK, decodifica el payload JWT (base64url) y verifica:
- Expiración: el claim
exp(timestamp Unix) debe estar en el futuro - Revocación: obtén periódicamente
/api/licensing/revocation-listy verifica si eljtidel JWT está en la lista de revocaciones - Derechos:
auris_lic.features,auris_lic.seats.max,auris_lic.devices.max
// JWT payload (decoded)
{
"jti": "key_abc123",
"iss": "auris",
"sub": "VIG-A8BC-D3EF-G4HJ-K5LM",
"exp": 1804723200,
"auris_lic": {
"features": ["threat-intel", "vuln-scan"],
"seats": { "max": 5 },
"devices": { "max": 3 }
}
}Para una validación offline completa con verificación de firma, usa la clave pública de Auris desde /.well-known/jwks.json. La mayoría de los lenguajes tienen bibliotecas JWT (por ej. System.IdentityModel.Tokens.Jwt para C#, crate jsonwebtoken para Rust, golang-jwt para Go).
Huella Digital del Dispositivo
Para licencias basadas en dispositivo, genera un identificador de máquina estable:
| Lenguaje | Método |
|---|---|
| C# | System.Management → Win32_ComputerSystemProduct.UUID o Environment.MachineName |
| Rust | crate machine-uid o /etc/machine-id en Linux |
| C/C++ | /etc/machine-id (Linux), IOPlatformUUID (macOS), registro MachineGuid (Windows) |
| Go | github.com/denisbrodbeck/machineid |
| Python | uuid.getnode() o platform.node() |
| Java | InetAddress.getLocalHost().getHostName() + dirección MAC |
La huella digital solo necesita ser una cadena estable y única para la máquina. Envíala a activate y deactivate.
Resumen
El patrón es el mismo en todos los lenguajes:
1. POST /api/licensing/validate {"key": "..."} → {valid, features, seats, ...}
2. POST /api/licensing/activate {"key": "...", "fingerprint": "..."} → 200 OK
3. POST /api/licensing/deactivate {"key": "...", "fingerprint": "..."} → 200 OKTres endpoints. Sin SDK requerido. Sin API key. Sin Bearer token. Solo HTTP + JSON.