logo

.NET

apikee for .NET — ASP.NET Core middleware, attribute, and Swashbuckle integration.

.NET

NuGet package

Installation

dotnet add package Apikee

ASP.NET Core

Three pieces in Program.cs wire up validation, Swagger, and request handling:

using Apikee;
using Apikee.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddApikee(o => {
    o.Secrets = [builder.Configuration["Apikee:Secret"]!];
    o.HeaderName = "x-api-key";      // default
    // o.ServerKey = builder.Configuration["Apikee:ServerKey"];
    // o.ProjectEnv = "my-app-production";
});

builder.Services.AddSwaggerGen(c => c.AddApikeeSecurityDefinition());

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();
app.UseApikee();

app.MapGet("/data", (HttpContext context) => {
    var claims = (ApikeeClaims) context.Items["apikee.claims"]!;
    return Results.Ok(new { claims.Tenant, claims.Scopes });
});

app.Run();

Opening Swagger UI after adding AddApikeeSecurityDefinition() shows a 🔒 lock icon on protected endpoints. The Authorize button lets you paste a key and test routes directly.

Controllers

Claims are stored on HttpContext.Items["apikee.claims"] after validation:

[HttpGet("/data")]
public IActionResult GetData()
{
    var claims = (ApikeeClaims) HttpContext.Items["apikee.claims"]!;
    return Ok(new { claims.Tenant, claims.Scopes });
}

Scope enforcement

Use the [Apikee] attribute on controllers or actions when you prefer attribute-based protection:

[ApiController]
[Apikee]                           // all actions in this controller
public class OrdersController : ControllerBase
{
    [HttpGet]
    public IActionResult List() { ... }

    [HttpPost]
    [Apikee(Scopes = "write")]     // additionally requires "write" scope
    public IActionResult Create([FromBody] CreateOrderRequest req) { ... }

    [HttpDelete("{id}")]
    [Apikee(Scopes = "admin")]     // additionally requires "admin" scope
    public IActionResult Delete(int id) { ... }
}

When both global UseApikee() middleware and [Apikee] attributes are present, the attribute acts as a second layer — it checks scope even after the middleware has already validated the key.

Key creation

Inject ApikeeClient (registered automatically by AddApikee()):

public class KeyController(ApikeeClient apikee) : ControllerBase
{
    [HttpPost("/keys")]
    [AllowAnonymous]
    public async Task<IActionResult> CreateKey(
        [FromQuery] string tenant,
        [FromQuery] string scopes = "read,write")
    {
        string key = await apikee.CreateAsync(
            tenant,
            keyOpts: new KeyOptions {
                Tenant = tenant,
                Scopes = scopes.Split(','),
                ExpiresIn = "90d",
                Meta = new Dictionary<string, object> {
                    ["plan"] = "pro",
                },
                // server mode extras:
                // Name = "Acme Mobile Backend",
                // ClientType = "service",
                // TemplateId = "clt_abc123",
                // IpWhitelist = ["203.0.113.0/24"],
            }
        );
        return StatusCode(201, new { key });
    }
}

Configuration

{
  "Apikee": {
    "Secret": "your-signing-secret",
    "ServerKey": "",
    "ProjectEnv": "my-app-production"
  }
}

Bind in Program.cs:

builder.Services.AddApikee(o =>
    builder.Configuration.GetSection("Apikee").Bind(o));

Configuration reference

OptionTypeDefaultDescription
Secretsstring[]requiredSigning secrets. First is current.
HeaderNamestring"x-api-key"Header to read the key from.
ServerKeystring?nullapikee.dev project key. Enables server mode.
ProjectEnvstring?nullapikee.dev project_env slug.
AutoRegisterEndpointsbooltrueRegister endpoints on first request (server mode).
AutoCreateClientsbooltrueAuto-create client on key issuance (server mode).
FailOpenbooltrueAllow through if server call fails.
ServerTimeoutTimeSpan3sTimeout for apikee.dev calls.

ApikeeClaims fields

FieldTypeDescription
IdstringUnique key ID
TenantstringTenant / owner
ScopesIReadOnlyList<string>Permission scopes
EnvironmentstringEnvironment tag
ExpiresAtDateTimeOffset?Expiry
NotBeforeDateTimeOffset?Not-valid-before
MetaIReadOnlyDictionary<string, object>User-defined metadata
RawKeystringOriginal key string

Errors

Validation failures use the same error codes as the other SDKs:

CodeCause
MISSING_KEYNo key in request header
INVALID_PREFIXKey doesn't start with apikee_
INVALID_FORMATMissing . separator
DECODE_ERRORInvalid base62 or JSON
INVALID_SIGNATUREHMAC check failed
EXPIREDexp timestamp is in the past
NOT_YET_VALIDnbf timestamp is in the future
INSUFFICIENT_SCOPEKey missing required scope
SERVER_REJECTEDapikee.dev rejected the request (server mode)

Source

github.com/apikee/apikee-dotnet

On this page