Authentication

Declare authentication as a first-class part of your service spec. Each operation identifies the auth scheme it requires by type, and code generators turn that into the matching runtime check — no JSON attributes, no string parsing, no per-controller glue.

1 Declare Auth Schemes on the Service

Add an auth_schemes array at the top level of your api.json. Each entry declares a scheme type that operations can reference. Code generators look up the type and emit the corresponding runtime helper.

"auth_schemes": [
  {
    "type": "hackathon_admin",
    "description": "Tenant admin for the hackathon tenant"
  },
  {
    "type": "session",
    "description": "Any logged-in user session"
  }
]

The reserved value none cannot be used as a scheme type — it is the explicit-public marker on operations.

2 Reference a Scheme on an Operation

Set auth on the operation to one of the declared scheme types. Code generators emit the matching runtime check; the service method receives the authenticated caller as its first argument.

"resources": {
  "event": {
    "operations": [
      {
        "method": "GET",
        "path": "/admin/events",
        "auth": "hackathon_admin"
      }
    ]
  }
}

3 Resource-Level Defaults & Per-Operation Overrides

In your input api.json you can set a default auth at the resource level so every operation inherits it. API Builder materializes the inheritance for you — the emitted service spec carries the effective scheme on each operation directly. Generators never need to walk back to the resource to find the auth value.

"resources": {
  "event": {
    "auth": "hackathon_admin",
    "operations": [
      { "method": "GET",  "path": "/admin/events" },
      { "method": "POST", "path": "/admin/events" },
      {
        "method": "GET",
        "path": "/admin/events/public-feed",
        "auth": "none"
      }
    ]
  }
}

Use "auth": "none" to opt a single operation out of an otherwise-protected resource. The generated controller emits no auth check for that op.

4 What Generators Produce

The Play controller generator wraps each protected operation in the runtime helper that matches the scheme type and passes the authenticated principal to your service method:

def getEvents(): Action[AnyContent] = Action.async { request =>
  withHackathonAdmin(request) { auth =>
    service.getEvents(auth).map(toGetEventsResult)
  }
}

Each generator decides how scheme types map to runtime helpers. If your generator does not recognize a scheme type, codegen fails — an unrecognized scheme is never silently dropped to public.

! Key Rules

  • Declare before reference — every operation.auth value (other than none) must appear in service.auth_schemes. Generators reject unknown references.
  • Reserved valuenone cannot be used as an auth_scheme type; it is the per-operation public marker.
  • Inheritance is materialized — resource-level defaults are flattened into each operation before the spec is emitted, so generators only ever read operation.auth.
  • Absent today, required tomorrow — an operation with no auth field is currently treated as public. A future revision will require the field; declare schemes now to be ready.

Resources

Ready to declare your auth schemes?

View api.json Format