# Security changes in v0.10

This release introduces a small but important, and **breaking**, change to how
Oaskit handles security. The goal is to make it easier to build “secure by
default” setups when you opt into a security plug.

## Summary

- `Oaskit.Plugs.ValidateRequest` now **always** calls the configured `:security`
  plug (when present), even if the OpenAPI operation has no security
  requirements (`security: nil`).
- This only affects projects that have configured a `:security` plug.

## Previous behaviour

Before v0.10:

- If an operation had no `security` defined and there was no global security
  requirement, `ValidateRequest` would not run any security logic for that
  route.
- Forgetting to add `security` to an operation could therefore leave an endpoint
  unintentionally open.

## New behaviour

From v0.10:

- As soon as you configure a security plug on `ValidateRequest`, it will run on
  **every** request handled with that plug.
- When an operation has no security defined, the plug receives `nil` as the
  `:security` option and can decide how to handle it.

## Deny-by-default with a security plug

One common use case is to treat “no security defined” as “deny access unless
explicitly marked as public”.

Here’s a simple example of rejecting any route that hasn’t been explicitly
marked as public:

<!-- rdmx :section format:true name:"plug-example" -->
```elixir
defmodule MyApp.SecurityPlug do
  @behaviour Plug

  @impl true
  def init(opts), do: opts

  @impl true
  def call(conn, opts) do
    case Keyword.fetch!(opts, :security) do
      nil ->
        conn
        |> Conn.send_resp(401, "unauthorized")
        |> Conn.halt()

      requirements ->
        validate_requirements(conn, requirements)
    end
  end

  defp validate_requirements(conn, requirements) do
    # your auth logic here
  end
end
```
<!-- rdmx /:section -->

You can invert that logic (treat `nil` as public, and only enforce checks when
requirements are present) if that better matches your application.

## Backwards-compatibility

- If you don’t configure a `:security` plug in your `ValidateRequest` options,
  behaviour is unchanged: routes without security definitions remain accessible.
- The new behaviour only applies once a security plug is configured, at which point it is invoked for every request.

