Adicionando OAuth2 a Jupyter Notebooks no Kubernetes

Built for Speed: ~10ms Latency, Even Under Load
Blazingly fast way to build, track and deploy your models!
- Handles 350+ RPS on just 1 vCPU — no tuning needed
- Production-ready with full enterprise support
TrueFoundry os usuários podem implantar Jupyter Notebooks em suas contas de nuvem pessoais, como AWS, Azure ou GCP. Este recurso permite que eles conduzam experimentos de aprendizado de máquina e trabalhos de treinamento em suas próprias máquinas com facilidade. Inicialmente, os notebooks implantados através da TrueFoundry eram protegidos usando uma combinação de nome de usuário e senha. No entanto, em resposta a solicitações generalizadas de clientes, integramos o Single Sign-On. Isso significa que os usuários agora podem acessar convenientemente seus notebooks com o mesmo login que usam para a TrueFoundry. Esta postagem do blog aprofunda os detalhes de como implementamos esse recurso.

Notebooks na TrueFoundry
A TrueFoundry usa internamente um fork do Kubeflow Notebook Controller para orquestrar a implantação de notebooks. O controlador oferece vários recursos que aproveitamos, como:
- Especificação de notebook simplificada: As APIs do Kubeflow Notebook são simples e o controlador orquestra a criação das implantações de Jupyter Notebook.
- Desativação Automática: O controlador desliga automaticamente o notebook após um certo período de inatividade. Isso é incrivelmente útil para nossos clientes que executam experimentos em notebooks suportados por máquinas GPU.
- Diretório Pessoal Persistente: O controlador se encarrega de criar um volume persistente que salva o progresso do usuário no notebook entre as sessões.
- Imagens base extensíveis: O controlador suporta um conjunto de imagens base de Jupyter Notebook e VS Code mantidas pela TrueFoundry. O usuário pode estender os recursos dessas imagens Docker adicionando um script de inicialização ou instalando bibliotecas específicas.
Para contextualizar, veja como é um objeto Kubeflow Notebook simples:
apiVersion: kubeflow.org/v1
kind: Notebook
metadata:
name: my-notebook
spec:
template:
spec:
containers:
- name: my-notebook
image: kubeflownotebookswg/jupyter:master
args:
[
"start.sh",
"lab",
"--LabApp.token=''",
"--LabApp.allow_remote_access='True'",
"--LabApp.allow_root='True'",
"--LabApp.ip='*'",
"--LabApp.base_url=/test/my-notebook/",
"--port=8888",
"--no-browser",
]
Autenticação Básica para Notebooks
Antes de implementar o OAuth2, a TrueFoundry oferecia aos usuários a opção de aprimorar a segurança de seus notebooks públicos, integrando a autenticação básica. Essa camada adicional de segurança era crucial para garantir que apenas indivíduos autorizados pudessem acessar o conteúdo sensível desses notebooks. Para implementar esse recurso, a TrueFoundry utilizou os recursos de plugins de WebAssembly (Wasm) dentro do proxy Istio, especificamente o Proxy Envoy.
O Istio, uma malha de serviço de código aberto, oferece uma estrutura para gerenciar as comunicações de rede entre várias cargas de trabalho de serviço. Com o Istio, a TrueFoundry conseguiu injetar lógica personalizada diretamente na camada de rede, que é gerenciada pelo proxy Envoy. Essa abordagem permitiu um controle e segurança eficazes do tráfego fluindo de e para seus Jupyter Notebooks. A chave para a implementação da autenticação básica foi o WasmPlugin, um recurso do Istio que facilita a implantação de módulos WebAssembly dentro do proxy Envoy.
Este WasmPlugin de autenticação básica é integrado a uma sequência de filtros de rede dentro do proxy Envoy. Esses filtros permitem a execução de funções de nível superior relacionadas a controle de acesso, transformação, enriquecimento de dados, auditoria e muito mais, aumentando assim a segurança e a funcionalidade geral da malha de serviço. Aqui está uma versão simplificada da especificação para adicionar o filtro de autenticação básica à cadeia de filtros do Envoy:
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: basic-auth
namespace: istio-ingress
spec:
phase: AUTHN
pluginConfig:
basic_auth_rules:
- credentials:
- user:pass
hosts: www.example.com
prefix: /secret/
selector:
matchLabels:
istio: ingressgateway
url: oci://ghcr.io/istio-ecosystem/wasm-extensions/basic_auth:1.12.0
OAuth2 para Notebook
Para implementar o OAuth2 em nossos notebooks, utilizamos um filtro Envoy, mas a abordagem difere da autenticação básica. Ao contrário da autenticação básica, onde pudemos inserir convenientemente um WasmPlugin pré-construído na cadeia de filtros, o OAuth2 exigiu uma solução mais personalizada. Para isso, empregamos um filtro HTTP especificamente projetado para OAuth. Na TrueFoundry, nosso sistema de Single Sign-On (SSO) se integra com FusionAuth, servindo como nosso provedor OAuth.
Veja como a especificação do Filtro Envoy se parece – consulte os comentários no arquivo para mais detalhes:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: truefoundry-notebook-tfy-oauth2 # Nome do EnvoyFilter
namespace: auth-test # Namespace onde o EnvoyFilter é implantado
spec:
workloadSelector:
labels:
truefoundry.com/application: truefoundry-notebook # Seletor que visa cargas de trabalho com rótulos específicos
configPatches:
- applyTo: CLUSTER
match:
context: SIDECAR_OUTBOUND
patch:
operação: ADICIONAR
valor:
nome: tfy-oauth2 # Nome do cluster para o serviço de autenticação OAuth2
tipo: LOGICAL_DNS # Tipo de descoberta de serviço (DNS)
tempo_limite_conexão: 5s # Tempo limite para estabelecer uma conexão
política_lb: ROUND_ROBIN # Política de balanceamento de carga
# outras configurações de balanceamento de carga
- aplicarA: HTTP_FILTER
correspondência:
contexto: SIDECAR_INBOUND
ouvinte:
cadeia_de_filtros:
filtro:
nome: "envoy.filters.network.http_connection_manager"
subfiltro:
nome: envoy.filters.http.jwt_authn
patch:
operação: INSERIR_ANTES # Inserindo este filtro antes do filtro de autenticação JWT
valor:
nome: envoy.filters.http.tfy-oauth # Nome do filtro OAuth
configuração_tipada:
"@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
configuração:
usar_token_de_atualização: false # Se deve usar um token de atualização
correspondente_de_passagem:
- nome: Authorization
correspondência_de_presença: true # Passar se o cabeçalho Authorization estiver presente
encaminhar_token_bearer: true # Encaminhar o token bearer para o upstream
tipo_de_autenticação: BASIC_AUTH # Tipo de autenticação usado
endpoint_de_token:
cluster: tfy-oauth2 # Cluster para o endpoint de token
uri: <token-endpoint-uri-of-oauth-provider>
tempo_limite: 5s # Tempo limite para o endpoint de token
endpoint_de_autorização: <authorization-endpoint-uri-of-oauth-provider>
uri_de_redirecionamento: https://%REQ(:authority)%/truefoundry-notebook/_auth/callback # URI de redirecionamento para o callback
correspondente_de_caminho_de_redirecionamento:
caminho:
exato: /truefoundry-notebook/_auth/callback # Caminho para a URI de redirecionamento
caminho_de_logout:
caminho:
exact: /truefoundry-notebook/_auth/signout # Caminho para sair
credentials:
client_id: <client-id-for-oauth>
token_secret:
# configuração para buscar o segredo do token
# leia mais sobre como buscamos segredos aqui:
# https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret
hmac_secret:
# configuração para buscar hmac
Quando um usuário tenta acessar um serviço protegido pelo filtro OAuth2 pela primeira vez, ele é redirecionado para o authorization_endpoint. Este endpoint é o URL do nosso Provedor OAuth externo, que, em nossa implementação, é o modal de login TrueFoundry baseado em FusionAuth. Este redirecionamento é uma etapa crítica no processo OAuth, guiando os usuários para um local seguro onde eles podem se autenticar e, consequentemente, conceder as permissões necessárias para acessar o serviço.
Assim que o login for concluído, o FusionAuth irá redirecioná-lo para o redirect_uri (configurado na especificação do filtro), adicionando um código de autorização secreto e temporário lá. Esta requisição é interceptada pelo filtro e ele faz uma requisição para token_endpoint, trocando o código por um token JWT. Finalmente, o filtro define cookies com o token JWT.
Acessos subsequentes ao serviço são passados pelo Filtro HTTP já que o cookie define o Authorization header com JWT como valor. O filtro é configurado para permitir a passagem de tais requisições (consulte pass_through_matcher na especificação). Para validar que o JWT é um token válido, criamos uma política de RequestAuthentication que verificará com o provedor OAuth:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
# ...
spec:
selector:
# ...
jwtRules:
- issuer: "truefoundry.com"
fromHeaders:
- name: Authorization
prefix: "Bearer "
audiences:
- <client-id>
jwksUri: <oauth-provider-jwks-uri>
forwardOriginalToken: true
Finalmente, adicionamos a Política de Autorização que especifica a quais requisições aplicar RequestAuthentication Queremos aplicar autorização a todos os pedidos na porta 8888:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: best-notebook-tfy-oauth2
namespace: auth-test
spec:
selector:
matchLabels:
truefoundry.com/application: best-notebook
action: DENY
rules:
- from:
- source:
notRequestPrincipals: ["*"]
to:
- operation:
ports:
- "8888"
TrueFoundry AI Gateway delivers ~3–4 ms latency, handles 350+ RPS on 1 vCPU, scales horizontally with ease, and is production-ready, while LiteLLM suffers from high latency, struggles beyond moderate RPS, lacks built-in scaling, and is best for light or prototype workloads.
The fastest way to build, govern and scale your AI
















.webp)







.webp)

.webp)
.webp)





.png)



