Origin.Client 1.0.0-ci13682
Origin Auth .NET SDK
Official .NET SDK for the Origin Auth Platform. Provides typed clients for every REST resource, automatic exponential-backoff retry with token refresh, and first-class dependency-injection support.
Package: Origin.Client
Version: 1.0.0 Targets: net10.0
License: MIT
Features
Typed clients (10 resources)
AuthClient— login, logout, token refresh, registration, password reset, user profileUsersClient— CRUD, list, searchTenantsClient— CRUD, settings, branding, MFA policyOAuthClient— authorize, token, introspect, revoke, OIDC discoveryMfaClient— TOTP/WebAuthn enroll/verify, recovery codes, device listSessionsClient— list, revoke, "log out everywhere"WebhooksClient— subscription CRUD, delivery list, replayBillingClient— plans, subscriptions, invoicesAuditClient— search, export, status, downloadHealthClient— ping, status (per-component health)- Plus a low-level
AuthenticationApiClient(Logto-compatible) wrapped byAuthClient.
Built-in resilience
- Polly-based RetryHandler with exponential back-off and jitter (defaults: 5 retries, 1s → 2s → 4s → 8s → 16s, max 32s).
- Retryable status codes: 429 Too Many Requests, 503 Service Unavailable, 504 Gateway Timeout.
- 401 Unauthorized: single refresh-and-retry via
OriginClientOptions.OnUnauthorizedAsync. - Network errors (timeouts, connection resets) trigger automatic retry.
- Fully configurable via
RetryPolicyOptions(e.g.ForTestingfor deterministic 100ms test delays).
Dependency-injection ready
builder.Services.AddOriginClient(options =>
{
options.BaseUrl = builder.Configuration["Origin:BaseUrl"]!;
options.ClientId = builder.Configuration["Origin:ClientId"]!;
options.ClientSecret = builder.Configuration["Origin:ClientSecret"];
});
The OriginClient facade (and all 10 typed sub-clients) can be injected into controllers, services, or background
workers.
Installation
# Add to your .NET project
dotnet add package Origin.Client
Configuration
Explicit options
var options = new OriginClientOptions
{
BaseUrl = "https://api.uat.origin-auth.com", // EXAMPLE — override per environment
ClientId = "your-client-id",
ClientSecret = "your-client-secret", // omit for public clients
TimeoutSeconds = 30, // per-request HTTP timeout
};
Environment variables (BR-23-NEW-008)
Every option has an environment-variable fallback. Explicit property assignments take precedence:
| Environment Variable | Option |
|---|---|
ORIGIN_AUTH_BASE_URL |
BaseUrl |
ORIGIN_AUTH_CLIENT_ID |
ClientId |
ORIGIN_AUTH_CLIENT_SECRET |
ClientSecret (nullable — empty string reads as null) |
ORIGIN_AUTH_ENVIRONMENT |
Environment (production / staging / development hint; diagnostics only) |
ORIGIN_AUTH_PERMISSIONS |
PermissionsToken (management API bearer token) |
ORIGIN_AUTH_WARN_ON_PRODUCTION_DEFAULT |
WarnOnProductionDefault (set 0 to suppress) |
// Zero-config: resolve everything from environment variables
builder.Services.AddOriginClient(_ => { });
When BaseUrl resolves to the production default (https://api.origin-auth.phanes.com) with no explicit
override, the SDK emits a one-shot trace warning at first request. Always set BaseUrl (or
ORIGIN_AUTH_BASE_URL) to your environment's API host. Other defaults: Authority derives from
{BaseUrl}/realms/origin; DefaultScope = openid profile email offline_access; ValidateSslCertificates
= true.
Quick start
using Origin.Client;
// Via DI
public class MyService(OriginClient origin) { ... }
// Or directly
var options = new OriginClientOptions
{
BaseUrl = "https://api.origin-auth.phanes.com",
ClientId = "your-client-id",
ClientSecret = "your-client-secret",
};
var httpClient = new HttpClient();
var origin = new OriginClient(httpClient, options);
// Login
var tokens = await origin.Auth.LoginAsync(new LoginRequest
{
ClientId = options.ClientId,
Username = "alice@example.com",
Password = "p@ssw0rd!",
});
// List users
var users = await origin.Users.ListAsync(tenantId: "tenant_123", page: 1, pageSize: 50);
foreach (var u in users.Items) Console.WriteLine(u.Email);
// Health check
var healthy = await origin.Health.PingAsync();
Authentication flows
Authorization Code (browser redirect)
// Server-side: exchange the code from the callback URL
var tokenResponse = await origin.OAuth.ExchangeCodeAsync(new ExchangeCodeRequest
{
Code = "auth-code-from-callback",
RedirectUri = "https://your-app.com/callback",
});
Client Credentials (machine-to-machine)
var token = await origin.OAuth.ClientCredentialsAsync(scope: "api:read");
Token introspection & revocation (RFC 7662 / RFC 7009)
var info = await origin.OAuth.IntrospectAsync(accessToken);
if (info.Active) { /* still valid */ }
await origin.OAuth.RevokeAsync(refreshToken, "refresh_token");
Retry semantics
The SDK automatically retries failed requests via the RetryHandler. Defaults:
| Failure | Action |
|---|---|
| 429 / 503 / 504 | Retry with exponential back-off (1s → 2s → 4s → 8s → 16s) |
| Network error (timeout, connection reset) | Retry with the same back-off |
| 401 Unauthorized | Single refresh-and-retry (requires OnUnauthorizedAsync handler) |
| 4xx (other) | Surface immediately, no retry |
| 5xx (other) | Retry with the same back-off |
Configure your own policy:
var handler = new RetryHandler(new HttpClientHandler(), new RetryPolicyOptions
{
MaxRetries = 10,
BaseDelaySeconds = 0.5,
MaxDelaySeconds = 60,
JitterFactor = 0.5,
});
Error handling
All client methods throw HttpRequestException on non-success status codes (after retries are exhausted). To inspect
the error body:
try
{
var user = await origin.Users.GetByIdAsync("invalid-id");
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
// Handle 404
}
For OAuth flows, the low-level AuthenticationApiClient throws typed ApiException subclasses
(RateLimitApiException, ErrorApiException, QuotaLimit).
Target framework
The package targets .NET 10 (net10.0). Origin.Client owns its public contracts and does not require a source-tree reference to Origin.Common.
License
MIT — see the LICENSE file for the full text.
Support
No packages depend on Origin.Client.
.NET 10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.14.0)
- Newtonsoft.Json (>= 13.0.3)
- Polly (>= 8.4.1)
- Polly.Extensions.Http (>= 3.0.0)
- System.IdentityModel.Tokens.Jwt (>= 8.14.0)
| Version | Downloads | Last updated |
|---|---|---|
| 1.0.0-ci13976 | 0 | 11/01/2026 |
| 1.0.0-ci13902 | 0 | 11/01/2026 |
| 1.0.0-ci13846 | 0 | 11/01/2026 |
| 1.0.0-ci13707 | 0 | 10/31/2026 |
| 1.0.0-ci13682 | 0 | 10/31/2026 |
| 1.0.0-ci13602 | 0 | 10/30/2026 |
| 1.0.0-ci13589 | 0 | 10/30/2026 |
| 1.0.0-ci13573 | 0 | 10/30/2026 |
| 1.0.0-ci13553 | 0 | 10/30/2026 |
| 1.0.0-ci13542 | 0 | 10/30/2026 |
| 1.0.0-ci13486 | 0 | 10/30/2026 |
| 1.0.0-ci13485 | 0 | 10/30/2026 |
| 1.0.0-ci13469 | 0 | 10/30/2026 |
| 1.0.0-ci13462 | 0 | 10/30/2026 |
| 1.0.0-ci13455 | 0 | 10/30/2026 |
| 1.0.0-ci13435 | 0 | 10/30/2026 |
| 1.0.0-ci13412 | 0 | 10/30/2026 |
| 1.0.0-ci13408 | 0 | 10/30/2026 |
| 1.0.0-ci13375 | 0 | 10/29/2026 |
| 1.0.0-ci13357 | 0 | 10/29/2026 |
| 1.0.0-ci13349 | 0 | 10/29/2026 |
| 1.0.0-ci13343 | 0 | 10/29/2026 |
| 1.0.0-ci13340 | 0 | 10/29/2026 |
| 1.0.0-ci13333 | 0 | 10/29/2026 |
| 1.0.0-ci13322 | 0 | 10/29/2026 |
| 1.0.0-ci13300 | 0 | 10/29/2026 |
| 1.0.0-ci13256 | 0 | 10/29/2026 |
| 1.0.0-ci13226 | 0 | 10/29/2026 |