Skip to content
Kona

Authorization

Authorization answers: may this user do that? After authentication identifies the user, gates and policies decide abilities.

  1. Resolve Gate from the container (registered by AuthServiceProvider) or construct one.
  2. Point the gate at the current user with setUserResolver { auth.user() }.
  3. define abilities or policy model classes; call allows / authorize in handlers or mount Authorize middleware.
gate.define("edit-post") { user, args ->
val post = args.firstOrNull() as? Post ?: return@define false
user?.getAuthIdentifier() == post.ownerId
}
if (gate.allows("edit-post", post)) { /* … */ }
gate.authorize("edit-post", post) // throws AuthorizationException (403)
gate.define("edit-post", (user, args) -> {
if (args.length == 0 || !(args[0] instanceof Post post)) return false;
return user != null && user.getAuthIdentifier().equals(post.ownerId);
});
gate.authorize("edit-post", post);
Method Behavior
define Register a named ability callback
allows / denies Boolean check (current user or explicit user)
any / none Combine several ability names
authorize Throw AuthorizationException when denied
before Global short-circuit (null continues; true/false settles)
policy Bind a Policy to a model class
discoverPolicy Load {SimpleName}Policy from a package by convention
forUser Scoped inspector (allows / any / authorize for one user)
has Whether an ability name is defined
gate.before { user, ability, _ ->
if (user is Admin) true else null
}
gate.any(listOf("edit", "publish"), post)
gate.none(listOf("delete"), post)
gate.policy(Post::class.java, object : Policy {
override fun before(user: Authenticatable?, ability: String): Boolean? =
if (ability == "admin") true else null
override fun authorize(user: Authenticatable?, ability: String, model: Any): Boolean {
val post = model as Post
return ability == "update" && user?.getAuthIdentifier() == post.ownerId
}
})

Convention discovery:

gate.discoverPolicy(Post::class.java, "app.policies") // loads app.policies.PostPolicy

Generate a stub with grind:

Terminal window
./grind make:policy Post --model=Post
./grind make:policy CommentPolicy --lang=java
router.put("/posts/{id}", handler).middleware(
Authorize(gate, "update") { request ->
arrayOf(Post.find(request.route("id")!!))
},
)

Denied checks throw AuthorizationException (HTTP 403).

In views, pass abilities via __abilities or a can map and use @can / @cannot (see Crema control structures). Template checks are data-driven — they do not call Gate automatically.