Skip to main content

Pick an auth strategy

The SDK supports two authentication strategies, both implementing IEksoAuth:
StrategyUse when
ApiKeyAuthServer-to-server, agents, CI runners, anything headless. Static credentials.
RefreshableBearerAuthYou already have an OAuth token pair (e.g. obtained via the CLI’s device-flow login or the web app’s auth-code grant). Auto-refreshes on expiry.
You only ever pass one of these to EksoClientOptions.Auth.

ApiKeyAuth

API keys are minted via the admin surface (POST /api/admin/api-key, or ekso api-key create --name "..." from the CLI). The response contains the raw key (ek_live_...) exactly once; capture it immediately and store somewhere safe.
using Ekso.Sdk;
using Ekso.Sdk.Authentication;

var client = new EksoClient(new EksoClientOptions
{
    Tenant = "acme",
    Auth = new ApiKeyAuth(Environment.GetEnvironmentVariable("EKSO_API_KEY")!),
});
Properties:
  • The key is sent as a Bearer token on every request.
  • It carries the permissions of the user who minted it.
  • It does not expire on a timer (unless ExpiresAt was set at mint time). Rotate on a policy.
  • The backend stamps API-key requests with Client=Sdk — see CLI/SDK marker.
Don’t:
  • Embed long-lived keys in client-side code, mobile binaries, or browser-shipped JS.
  • Commit keys to source control. Use a secrets manager (KeyVault, AWS Secrets Manager, env-var injection from CI).

RefreshableBearerAuth

Use this when you’ve obtained an access + refresh token pair from an interactive flow (typically OAuth 2.0 device code or authorization-code-with-PKCE).
using Ekso.Sdk;
using Ekso.Sdk.Authentication;

var auth = new RefreshableBearerAuth(
    accessToken: stored.AccessToken,
    refreshToken: stored.RefreshToken,
    tokenEndpoint: new Uri("https://acme.ekso.app/token"),
    clientId: stored.ClientId,
    expiresAt: stored.ExpiresAt);

// Persist rotations so the next process picks up the rotated refresh token.
auth.TokensRefreshed += (_, e) =>
{
    SaveCredentials(new StoredCredentials
    {
        AccessToken = e.AccessToken,
        RefreshToken = e.RefreshToken,
        ExpiresAt = e.ExpiresAt,
    });
};

var client = new EksoClient(new EksoClientOptions
{
    Tenant = "acme",
    Auth = auth,
});
Properties:
  • The SDK transparently exchanges the refresh token for a new access + refresh pair when the access token nears expiry.
  • The TokensRefreshed event fires after each rotation so you can persist the new pair. Without this hook, the next process invocation would try to refresh with a token the backend has already invalidated and trigger family-rotation replay detection.
  • Device-flow tokens carry Client=Cli; webapp authorization-code tokens carry no client claim (treated as Web at the read site).

Custom HTTP base URL

For local development or self-hosted instances, override the base URL:
var client = new EksoClient(new EksoClientOptions
{
    Tenant = "devinc",
    Auth = new ApiKeyAuth(localKey),
    BaseUrl = "https://devinc.localhost:7070",
});
The default base URL is https://{Tenant}.ekso.app.

Logging out / revoking

For ApiKeyAuth: revoke via the admin surface (POST /api/admin/api-key/{id}/revoke or ekso api-key delete <id>). The key stops working immediately on subsequent calls. For RefreshableBearerAuth: there is no client-side “logout” — discard the stored token pair and the user’s session is effectively gone. The refresh token expires server-side on a sliding window of inactivity.

Token-store integration

The CLI persists RefreshableBearerAuth tokens to a per-tenant credential store on disk (see EksoClientFactory in Ekso.Cli). If you’re embedding the SDK in your own app, design your token store the same way — keyed by (Tenant, ClientId, Environment) so multi-tenant or multi-environment installs don’t collide.

Next steps