Autenticación
Glue2 soporta tres mecanismos de autenticación: Claves API, Sesiones y OAuth 2.0. Cada endpoint puede configurarse para requerir autenticación (Require) o hacerla opcional (Optional). Las solicitudes no autenticadas a endpoints Require reciben una respuesta 401 Unauthorized.
Claves API
Las claves API proporcionan autenticación máquina a máquina. Cada clave consta de dos partes: un Api-Key (identificador público) y un Api-Secret (secreto privado). El secreto se almacena como un hash bcrypt y no se puede recuperar después de la creación.
curl -X POST "https://api.hola.cloud/api/v0/lambdas" \
-H "Api-Key: TU_API_KEY" \
-H "Api-Secret: TU_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"name": "mi-funcion", "runtime": "js", "code": "..."}'POST /api/v0/lambdas HTTP/1.1
Host: api.hola.cloud
Api-Key: TU_API_KEY
Api-Secret: TU_API_SECRET
Content-Type: application/json
{"name": "mi-funcion", "runtime": "js", "code": "..."}package main
import (
"fmt"
"io"
"net/http"
"encoding/json"
"strings"
)
func main() {
payload := map[string]any{"code": "...", "name": "mi-funcion", "runtime": "js"}
bodyBytes, err := json.Marshal(payload)
if err != nil {
panic(err)
}
body := string(bodyBytes)
req, err := http.NewRequest("POST", "https://api.hola.cloud/api/v0/lambdas", strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Api-Key", "TU_API_KEY")
req.Header.Set("Api-Secret", "TU_API_SECRET")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(responseBody))
}
<?php
$payload = ['code' => '...', 'name' => 'mi-funcion', 'runtime' => 'js'];
$body = json_encode($payload);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.hola.cloud/api/v0/lambdas',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Api-Key: TU_API_KEY',
'Api-Secret: TU_API_SECRET',
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
if ($response === false) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
echo $response;
import requests
import json
headers = {
"Api-Key": "TU_API_KEY",
"Api-Secret": "TU_API_SECRET",
"Content-Type": "application/json",
}
payload = {"code": "...", "name": "mi-funcion", "runtime": "js"}
body = json.dumps(payload)
response = requests.request(
"POST",
"https://api.hola.cloud/api/v0/lambdas",
headers=headers,
data=body
)
print(response.text)
const payload = {"code": "...", "name": "mi-funcion", "runtime": "js"};
const response = await fetch("https://api.hola.cloud/api/v0/lambdas", {
method: "POST",
headers: {
"Api-Key": "TU_API_KEY",
"Api-Secret": "TU_API_SECRET",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
console.log(await response.text());
const payload = {"code": "...", "name": "mi-funcion", "runtime": "js"};
const response = await fetch("https://api.hola.cloud/api/v0/lambdas", {
method: "POST",
headers: {
"Api-Key": "TU_API_KEY",
"Api-Secret": "TU_API_SECRET",
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
const text = await response.text();
console.log(text);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
var payload = Map.of("code", "...", "name", "mi-funcion", "runtime", "js");
var body = new ObjectMapper().writeValueAsString(payload);
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.hola.cloud/api/v0/lambdas"))
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.header("Api-Key", "TU_API_KEY")
.header("Api-Secret", "TU_API_SECRET")
.header("Content-Type", "application/json")
.build();
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Las claves API pueden limitarse por proyecto y reglas de host:
- Proyectos: La clave solo es válida para el proyecto configurado.
- Reglas de host: Restringen hosts virtuales y metadatos opcionales por host.
Los ámbitos de ruta y método HTTP no forman parte del modelo actual.
Autenticación Opcional vs Requerida
- Require: El endpoint rechaza solicitudes no autenticadas con
401. - Optional: El endpoint acepta tanto solicitudes autenticadas como anónimas. Las solicitudes autenticadas reciben encabezados inyectados; las anónimas pasan sin ellos.
Cuando se proporciona una clave API válida, Glue2 inyecta el encabezado X-Glue-Authentication como JSON en la solicitud proxy.
Sesiones
La autenticación basada en sesiones es utilizada por los usuarios del navegador en la Consola de HolaCloud. Cuando un usuario inicia sesión a través de auth.hola.cloud, el servicio de autenticación crea una sesión almacenada en InceptionDB. El ID de sesión se devuelve como una cookie HTTP-only, Secure y SameSite.
1# Las sesiones son gestionadas automáticamente por el navegador.
2# Para acceso por API, usa claves API o tokens OAuth.
Las cookies de sesión se adjuntan automáticamente a las solicitudes a los subdominios de HolaCloud. Glue2 lee la cookie, busca la sesión en InceptionDB y la valida antes de reenviar la solicitud.
OAuth 2.0 / Google Auth
Los usuarios de la Consola pueden autenticarse mediante Google OAuth 2.0. El flujo funciona de la siguiente manera:
- El usuario hace clic en "Iniciar sesión con Google" en la página de inicio de sesión de la Consola.
- El navegador redirige al endpoint de autorización de Google.
- El usuario concede permiso y Google redirige de vuelta con un código de autorización.
- La Consola intercambia el código por un token de acceso y un token ID.
- El token ID se envía a Glue2, que lo valida y crea una sesión.
Los tokens OAuth también pueden usarse directamente para llamadas API:
curl "https://api.hola.cloud/api/v0/lambdas" \
-H "Authorization: Bearer TU_TOKEN_OAUTH"GET /api/v0/lambdas HTTP/1.1
Host: api.hola.cloud
Authorization: Bearer TU_TOKEN_OAUTH
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://api.hola.cloud/api/v0/lambdas", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer TU_TOKEN_OAUTH")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(responseBody))
}
<?php
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.hola.cloud/api/v0/lambdas',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer TU_TOKEN_OAUTH',
],
]);
$response = curl_exec($ch);
if ($response === false) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
echo $response;
import requests
headers = {
"Authorization": "Bearer TU_TOKEN_OAUTH",
}
response = requests.request(
"GET",
"https://api.hola.cloud/api/v0/lambdas",
headers=headers
)
print(response.text)
const response = await fetch("https://api.hola.cloud/api/v0/lambdas", {
method: "GET",
headers: {
"Authorization": "Bearer TU_TOKEN_OAUTH"
}
});
console.log(await response.text());
const response = await fetch("https://api.hola.cloud/api/v0/lambdas", {
method: "GET",
headers: {
"Authorization": "Bearer TU_TOKEN_OAUTH"
}
});
const text = await response.text();
console.log(text);
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.hola.cloud/api/v0/lambdas"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.header("Authorization", "Bearer TU_TOKEN_OAUTH")
.build();
var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Resumen del Flujo de Autenticación
1Método Credenciales Uso típico Ámbito
2───────────────────────────────────────────────────────────────────────
3Clave API Api-Key + Api-Secret Máquina a máquina Proyecto/Reglas de host
4Sesión Cookie (http-only) Usuarios de navegador Identidad de usuario
5OAuth 2.0 Token Bearer Consola / SSO Identidad de Google
Gestión de Claves API a Través de la Consola
Las claves API se gestionan en la Consola de HolaCloud en Configuración > Claves API. Desde allí puedes:
- Crear nuevos pares de claves (Api-Key + Api-Secret)
- Ver claves existentes (el secreto se muestra solo una vez al crearlo)
- Revocar claves
- Establecer ámbitos de clave
Mejores Prácticas de Seguridad
- Rota las claves regularmente: Genera nuevas claves y actualiza tus aplicaciones periódicamente.
- Mínimo privilegio: Limita cada clave al conjunto mínimo de proyectos y reglas de host necesarios.
- Solo HTTPS: Usa siempre
https://— nunca envíes credenciales por HTTP plano. - Almacena secretos de forma segura: Usa variables de entorno o un gestor de secretos. Nunca hardcodees secretos en el código fuente.
- Revoca claves comprometidas inmediatamente: Usa la Consola o la API para revocar claves si se exponen.
Siguientes Pasos
- Aprende a crear y gestionar claves API en Gestión de Claves API.
- Revisa la arquitectura y el enrutamiento en Arquitectura y Enrutamiento.
Comentarios