API Keys
View SourceA note on API Keys
API keys are generated using AshAuthentication.Strategies.ApiKey.GenerateApiKey
. See the module docs for more information.
The API key is generated using a random byte string and a prefix. The prefix is used to generate a key that is compliant with secret scanning. You can use this to set up an endpoint that will automatically revoke leaked tokens, which is an extremely powerful and useful security feature. We only store a hash of the api key. The plaintext api key is only available in api_key.__metadata__.plaintext_api_key
immediately after creation.
See the guide on Github for more information.
Api key expiration/validity is otherwise up to you. The configured api_key_relationship
should include those rules in the filter.
For example:
has_many :valid_api_keys, MyApp.Accounts.ApiKey do
filter expr(valid)
end
Installation
With Igniter (recommended)
Use mix ash_authentication.add_strategy api_key
to install this strategy, and modify the generated resource
to suit your needs.
Manually
Create an API key resource
defmodule MyApp.Accounts.ApiKey do
use Ash.Resource,
data_layer: AshPostgres.DataLayer,
authorizers: [Ash.Policy.Authorizer]
actions do
defaults [:read, :destroy]
create :create do
primary? true
accept [:user_id, :expires_at]
change {AshAuthentication.Strategy.ApiKey.GenerateApiKey, prefix: :myapp, hash: :api_key_hash}
end
end
attributes do
uuid_primary_key :id
attribute :api_key_hash, :binary do
allow_nil? false
sensitive? true
end
# In this example, all api keys have an expiration
# Feel free to rework this however you please
attribute :expires_at, :utc_datetime_usec do
allow_nil? false
end
end
relationships do
belongs_to :user, MyApp.Accounts.User do
allow_nil? false
end
end
calculations do
calculate :valid, :boolean, expr(expires_at > now())
end
identities do
identity :unique_api_key, [:api_key_hash]
end
policies do
# Allow AshAuthentication to work with api keys as necessary
bypass always() do
authorize_if AshAuthentication.Checks.AshAuthenticationInteraction
end
end
end
Add the strategy to your user
authentication do
...
strategies do
api_key do
api_key_relationship :valid_api_keys
end
end
end
Relate users to valid api keys
relationships do
has_many :valid_api_keys, MyApp.Accounts.ApiKey do
filter expr(valid)
end
end
Add the sign_in_with_api_key action
Add the action to your user resource
read :sign_in_with_api_key do
argument :api_key, :string, allow_nil?: false
prepare AshAuthentication.Strategy.ApiKey.SignInPreparation
end
Use the plug in your router/plug pipeline
See AshAuthentication.Strategies.ApiKey.Plug
for all available options.
In Phoenix, for example, you might add this plug to your
:api
pipeline.
pipeline :api do
...
plug AshAuthentication.Strategy.ApiKey.Plug,
resource: MyApp.Accounts.User
end