Guia — IInboundAuthScheme
Um esquema de autenticação novo, ativado por scheme: num spec.auth.schemes. Os quatro esquemas
embutidos (jwt, oidc, mtls, basic — ver Autenticação e
autorização) são implementados exatamente pelo mesmo
contrato descrito aqui.
Exemplo mínimo
using Microsoft.AspNetCore.Authentication;
using Microsoft.OpenApi;
using Pipevine.Core.Configuration;
using Pipevine.Model.Auth;
using Pipevine.Security.Abstractions;
using Pipevine.Security.Abstractions.Secrets;
public sealed class AcmeInboundAuthScheme(ISecretResolverRegistry secretResolvers) : IInboundAuthScheme
{
// Roda UMA vez por esquema declarado, no startup — antes do host subir. Lançar aqui derruba
// o startup, não uma requisição.
public void Configure(AuthenticationBuilder builder, AuthSchemeDefinition definition)
{
var config = PipevineNodeJsonConverter.ToJsonNode(definition.Config);
var secretRef = config?["secret"]?.GetValue<string>()
?? throw new InvalidOperationException($"Scheme '{definition.Id}': requer 'secret'.");
// Credencial nunca literal no YAML — sempre ${secret:...}.
if (!SecretReference.IsSecretReference(secretRef))
{
throw new InvalidOperationException($"Scheme '{definition.Id}': 'secret' precisa ser ${{secret:...}}.");
}
var secret = SecretReference.ResolveAsync(secretRef, secretResolvers, CancellationToken.None).AsTask().GetAwaiter().GetResult();
builder.AddScheme<AcmeSchemeOptions, AcmeAuthenticationHandler>(definition.Id, options =>
{
options.Secret = secret;
});
}
// Opcional, mas fortemente recomendado — é o que faz o esquema aparecer no Swagger gerado.
public OpenApiSecurityScheme? DescribeForOpenApi(AuthSchemeDefinition definition) => new()
{
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
Name = "X-Acme-Signature",
};
}
O AuthenticationHandler<TOptions> em si é ASP.NET Core puro — nenhuma API específica do Pipevine
além de receber a claims principal em input.claims (via IPrincipalProjector, abaixo).
Ativação
spec:
auth:
default: { scheme: acme, ref: partner-acme }
schemes:
- { id: partner-acme, scheme: acme, secret: "${secret:env:ACME_SHARED_SECRET}" }
services.AddPipevineSecurity(); // idempotente
services.AddKeyedSingleton<IInboundAuthScheme, AcmeInboundAuthScheme>("acme");
Complementos
IAuthorizationRule— novas formas de autorização além de scopes/roles/claims/expr.IPrincipalProjector— controla como as claims chegam eminput.claims. O padrão projeta todas as claims doClaimsPrincipal; um esquema pode registrar o seu próprio para achatar/renomear campos.
Regra absoluta: nunca aceite credencial literal
Toda credencial de um esquema (senha, chave de assinatura, segredo de cliente) precisa ser exigida
como referência ${secret:...}, nunca como valor literal no YAML — os quatro esquemas embutidos
(veja basic, por exemplo) derrubam o build com uma mensagem clara quando encontram um literal onde
uma referência é esperada. Um esquema de terceiro deve seguir a mesma regra.
Para onde ir daqui
- Visão geral de extensibilidade
ISecretResolver— de onde vêm os valores por trás de${secret:...}.- Autenticação e autorização — os quatro esquemas embutidos, do ponto de vista de quem os usa.