Apikee

ASP.NET Core Example

A complete ASP.NET Core Notes API protected with apikee.

ASP.NET Core Example

A complete Notes API with [Apikee] attribute, per-action scope enforcement, and Swashbuckle auto-injection.

Run it

cd examples/aspnet-core && dotnet run

Open https://localhost:5001/swagger.

Setup

// Program.cs
builder.Services.AddApikee(o => {
    o.Secrets    = [builder.Configuration["Apikee:Secret"]!];
    // o.ServerKey  = builder.Configuration["Apikee:ServerKey"];
    // o.ProjectEnv = "my-app-production";
});
builder.Services.AddSwaggerGen(c => c.AddApikeeSecurityDefinition());
app.UseApikee();

Controllers

// Public — no [Apikee] attribute
[ApiController, Route("keys")]
public class KeysController(ApikeeClient apikee) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create([FromQuery] string tenant)
    {
        string key = await apikee.CreateAsync(tenant,
            keyOpts: new KeyOptions { Tenant = tenant, Scopes = ["read","write"] });
        return StatusCode(201, new { key });
    }
}

// Protected — [Apikee] on the controller
[ApiController, Route("notes"), Apikee]
public class NotesController : ControllerBase
{
    private ApikeeClaims Claims =>
        (ApikeeClaims) HttpContext.Items["apikee.claims"]!;

    [HttpGet]
    public IActionResult List() => Ok(new { Claims.Tenant });

    [HttpPost, Apikee(Scopes = "write")]         // requires write
    public IActionResult Create([FromBody] CreateNoteRequest req)
        => StatusCode(201, new { req.Title });

    [HttpDelete("{id}"), Apikee(Scopes = "admin")] // requires admin
    public IActionResult Delete(int id) => Ok(new { deleted = id });
}

Try it

curl -sk -X POST "https://localhost:5001/keys?tenant=acme"
export KEY="apikee_..."
curl -sk -H "x-api-key: $KEY" https://localhost:5001/notes
curl -sk -X POST -H "x-api-key: $KEY" -H "Content-Type: application/json" \
  -d '{"title":"Buy milk"}' https://localhost:5001/notes
# 403 — needs admin
curl -sk -X DELETE -H "x-api-key: $KEY" https://localhost:5001/notes/1

On this page