.NET
apikee for .NET — ASP.NET Core middleware, attribute, and Swashbuckle integration.
.NET
NuGet package
Installation
dotnet add package ApikeeASP.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
| Option | Type | Default | Description |
|---|---|---|---|
Secrets | string[] | required | Signing secrets. First is current. |
HeaderName | string | "x-api-key" | Header to read the key from. |
ServerKey | string? | null | apikee.dev project key. Enables server mode. |
ProjectEnv | string? | null | apikee.dev project_env slug. |
AutoRegisterEndpoints | bool | true | Register endpoints on first request (server mode). |
AutoCreateClients | bool | true | Auto-create client on key issuance (server mode). |
FailOpen | bool | true | Allow through if server call fails. |
ServerTimeout | TimeSpan | 3s | Timeout for apikee.dev calls. |
ApikeeClaims fields
| Field | Type | Description |
|---|---|---|
Id | string | Unique key ID |
Tenant | string | Tenant / owner |
Scopes | IReadOnlyList<string> | Permission scopes |
Environment | string | Environment tag |
ExpiresAt | DateTimeOffset? | Expiry |
NotBefore | DateTimeOffset? | Not-valid-before |
Meta | IReadOnlyDictionary<string, object> | User-defined metadata |
RawKey | string | Original key string |
Errors
Validation failures use the same error codes as the other SDKs:
| Code | Cause |
|---|---|
MISSING_KEY | No key in request header |
INVALID_PREFIX | Key doesn't start with apikee_ |
INVALID_FORMAT | Missing . separator |
DECODE_ERROR | Invalid base62 or JSON |
INVALID_SIGNATURE | HMAC check failed |
EXPIRED | exp timestamp is in the past |
NOT_YET_VALID | nbf timestamp is in the future |
INSUFFICIENT_SCOPE | Key missing required scope |
SERVER_REJECTED | apikee.dev rejected the request (server mode) |
