Authorizer Lambda con Auth0 y JWT

Clase 20 de 30Curso de Ciberseguridad para Desarrollo Web

Resumen

Proteger un endpoint con Auth0, un Lambda authorizer y API Gateway es directo cuando dominas la mecánica del JWT, la construcción de IAM policy y el despliegue con Terraform. Aquí verás cómo asegurar get metrics, validar el token con go-jose y probarlo con Postman, siguiendo buenas prácticas y sin pasos innecesarios.

¿Cómo se configura Auth0 para la aplicación y el API?

La base está en Applications y APIs. Se trabaja con una regular web application llamada myapp, y un API llamado mycourse API. El identifier del API se usa luego en las requests del token. En Allowed Callback URLs, el callback redirige a Google. En Connections, debe estar activa la base de datos de usuarios creada.

  • Verifica que myapp sea regular web application.
  • Ajusta Allowed Callback URLs con la redirección a Google.
  • Activa la conexión a la base de datos de usuarios.
  • En APIs, confirma settings e identifica el identifier del API.
  • En Machine to Machine Applications, cambia el apuntador de la app generada automáticamente a myapp.
  • Deshabilita la test application.

Estos parámetros garantizan que el issuer, la audience y el payload del JWT coincidan con lo configurado y que el flujo de autenticación sea consistente.

¿Cómo implementar un Lambda authorizer en Go con go-jose?

Se crea una nueva carpeta Authorizer con el archivo principal main. Un Lambda authorizer recibe un request distinto al de otras Lambdas y debe devolver una IAM policy con efecto de permitir o denegar. Se implementan dos métodos: uno para aceptar y otro para rechazar, incluyendo un motivo al denegar para facilitar el debug.

  • Dos salidas claras: allow request o deny request con policy explícita.
  • Handler especializado: usa el tipo de request de API Gateway v2 custom authorizer.
  • Log de evento: se serializa el evento a JSON para inspección.
  • Rutas: si el path apunta a commits (GitHub), se permite temporalmente todo.
  • Validación: si no es commits, se valida el token de Auth0 con go-jose.

¿Qué estructura tiene la policy de IAM?

La respuesta del authorizer es una API Gateway custom authorizer response con una policy. Cuando se deniega, se añade una razón para auditoría. Cuando se permite, se especifica la ruta (resource) a invocar.

// Esqueleto ilustrativo en Go.
func denyRequest(reason string) (interface{}, error) {
    // Retorna policy con Effect: "Deny" y razón para logs.
    return /* API Gateway custom authorizer response */, nil
}

func allowRequest(resource string) (interface{}, error) {
    // Retorna policy con Effect: "Allow" para el resource dado.
    return /* API Gateway custom authorizer response */, nil
}

¿Cómo extraer y validar el bearer token?

El token llega en el header de authorization. Si falta, se deniega con “missing auth0 token”. Luego se elimina el prefijo bearer con TrimPrefix y se valida.

func handler(event APIGatewayV2CustomAuthorizerV2Request) (interface{}, error) {
    // Ruta para construir el resource de la policy y conocer el path.
    route := /* resource/ruta destino */
    path := event.RequestContext.HTTP.Path

    // Log del evento.
    b, _ := json.Marshal(event)
    println(string(b))

    // Permitir temporalmente commits.
    if strings.Contains(path, "commits") {
        return allowRequest(route)
    }

    // Extraer token del header.
    authToken := event.Headers["authorization"]
    if authToken == "" {
        return denyRequest("missing auth0 token")
    }

    tokenString := strings.TrimPrefix(authToken, "bearer ")
    if tokenString == "" {
        return denyRequest("missing auth0 token")
    }

    return validate_token(tokenString, route)
}

¿Qué hace validate_token con jose/go-jose?

Se importa la librería con go get jose/go-jose y se usa el método parseSignet para validar y decodificar el JWT. Si falla, se deniega con “invalid auth0 token” y el error; si pasa, se permite la ruta indicada.

func validate_token(authToken, route string) (interface{}, error) {
    // Validar y decodificar el JWT de Auth0.
    _, err := jose.ParseSignet(authToken)
    if err != nil {
        return denyRequest("invalid auth0 token: " + err.Error())
    }
    return allowRequest(route)
}

func main() {
    // Arranque de la Lambda con el handler.
    lambda.Start(handler)
}

Habilidades y conceptos aplicados: construcción de IAM policy allow/deny. Manejo de headers y prefijos bearer. Validación de JWT con go-jose. Serialización a JSON para logging. Diseño de handler para API Gateway v2 custom authorizer.

¿Cómo desplegar y probar el authorizer con Terraform y Postman?

Se crea el makefile de Authorizer, se empaqueta y se sube a S3. Luego se provisiona con Terraform y se adjunta en API Gateway al endpoint de get metrics. Finalmente, se obtiene un access token y se prueba con Postman.

  • En Authorizer: go mod vendor y go mod tidy.
  • Empaquetado: make publish para subir el binario a S3.
  • Infra con Terraform: duplicar config de get metrics y renombrar a Authorizer.
  • Ejecutar terraform plan y terraform apply.
  • En AWS Console: API Gateway → Authorization → Create and attach authorizer.
  • Tipo: lambda. Nombre: auth de get metrics. Payload format: 2. Respuesta: IAM policy.
  • Generar token: usar el endpoint de get token, validar que el client ID corresponda a la aplicación de Auth0, completar el login y extraer el access token.
  • Probar en Postman: Authorization → Bearer Token, pegar el token.
  • Resultado esperado: “hello from metrics” con token válido.
  • Si alteras el token: acceso denegado con mensaje de error a mejorar.

¿Te gustaría que ampliemos el manejo de errores o la validación de claims del JWT? Comparte tus preguntas y cuéntame qué paso quieres ver con más detalle.