2
votes

I am using Guardian to set up JWT authentication. It is recommended to use a JWK (Json Web Key) to encrypt / sign the JWT. To generate said JWK I use JOSE.JWK.

Since my key file will be probably stored in source control, I want it to be password protected. The password is passed into the elixir app via System.get_env (to access environment variables).

I can generate the file and also read it back in with a password. But it fails in my config files like config/dev.exs. The error is

** (Mix.Config.LoadError) could not load config config/dev.exs ** (CompileError) config/dev.exs:2: module JOSE.JWK is not loaded and could not be found

My dev.exs:

use Mix.Config

# Configure Guardian for JWT Authentication
config :guardian, Guardian,
  allowed_algos: ["HS512"], # optional
  verify_module: Guardian.JWT,  # optional
  issuer: "MyApp",
  ttl: { 30, :days },
  verify_issuer: true, # optional
  secret_key:  System.get_env("GUARDIAN_KEY_PASSPHRASE") |> JOSE.JWK.from_file(System.get_env("GUARDIAN_KEY_FILE")),
  serializer: MyApp.GuardianSerializer

In the console everything works fine. So I guess when the config files are parsed, the modules aren't loaded yet. Is there a way to solve this?

Edit: It seems to have to do with when modules are loaded and how and when configuration files are evaluated and compiled. Wrapping the calls to JSON.JWK in an anonymous function for example works:

use Mix.Config

# Configure Guardian for JWT Authentication
config :guardian, Guardian,
  allowed_algos: ["HS512"], # optional
  verify_module: Guardian.JWT,  # optional
  issuer: "MyApp",
  ttl: { 30, :days },
  verify_issuer: true, # optional
  secret_key: fn -> System.get_env("GUARDIAN_KEY_PASSPHRASE") |> JOSE.JWK.from_file(System.get_env("GUARDIAN_KEY_FILE")) end,
  serializer: MyApp.GuardianSerializer
1
This might be obvious, but I need to ask. Have you added {:jose, "~> 1.7"}, {:poison, "~> 2.1"} to deps in mix.exs and run mix deps.get?tkowal
@tkowal JOSE is of course in the dependencies and it also works in the console. I think it has to do with how and when the configuration is loaded and compiled and when modules are loaded. I updated my question accordinglyOle Spaarmann
By "works in console" you mean it works in iex? This is strange, because iex uses the same config. One more obvious thing I have to ask :P Have you run mix compile? I believe iex -S mix run can compile modules in the path on demand while mix run can't.tkowal
I mean iex, sorry, old Rails habits... The thing is: It will not compile if I don't wrap the calls in an anonymous function, that is the problem. It fails with the error that JOSE.JWK is not available.Ole Spaarmann
Is it possible to share the app with us? Or minimal example at least? I would like to play with it to check what happens under the hood.tkowal

1 Answers

1
votes

Only the master branch of Guardian supports functions in the config.exs file. The released versions (0.10.x) do not support functions.

The issue is being tracked here: https://github.com/ueberauth/guardian/issues/136. You can see the new code here: https://github.com/ueberauth/guardian/blob/master/lib/guardian.ex#L292-296, especially line 294