Skip to content

Added new API new_token_from_jwt#1604

Open
prioux wants to merge 3 commits intoaces:masterfrom
prioux:jwt_token
Open

Added new API new_token_from_jwt#1604
prioux wants to merge 3 commits intoaces:masterfrom
prioux:jwt_token

Conversation

@prioux
Copy link
Member

@prioux prioux commented Mar 17, 2026

Using shared secrets, external services can ask for CBRAIN API tokens for users.

Using shared secrets, external services can ask for
CBRAIN API tokens for users.
@prioux prioux self-assigned this Mar 17, 2026
@prioux prioux added Enhancement Priority: High Security API API issues or Swagger description Admin Features or bugs related to administrative features labels Mar 17, 2026
@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

I will provide precise instructions on how to review/test this new code.

@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

Step 1: when checking out this branch, make sure to run "bundle install" because there are changes in the Gemfile. the "jwt" gem has been upgraded and the "shannon" gem is new.

@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

Step 2. In the rails console, pick a NormalUser of your choice and provide them with a secret:

irb> u=NormalUser.first # or any user you want
irb> secret="make a long string here" # or call CbrainSession.random_session_id
irb> u.set_shared_secret_for_client("loris", secret)

@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

Step 3: in the console, built yourself a token as if you were "loris":

irb> tok=JWT.encode( { :user_id => u.id, :client => 'loris' }, u.get_shared_secret_for_client('loris'), 'HS256')

(btw, you can also just use the variable "secret" in the second argument)

Copy the resulting string to your clipboard, we'll use it with curl in the next step

@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

Step 4: send the JWT encoded token (the string you got in step 3) to CBRAIN using curl:

bash> curl -X POST \
  -H 'Content-type: application/json' \
  -H 'Accept: application/json' \
  -d '{"jwt": "eyJhbGci reset_of_token here"}' \
  http://localhost:3000/users/new_token_from_jwt

Curl should print out CBRAIN's answer, a similary JSON output.

@prioux
Copy link
Member Author

prioux commented Mar 17, 2026

Step 5: Check the rails logs and try bad things

The rails logs shoudl have lines that say:

Started POST "/users/new_token_from_jwt" for ::1 at 2026-03-17 15:12:33 -0400
Processing by UsersController#new_token_from_jwt as JSON
  Parameters: {"jwt"=>"blahblah"}
 (...)
  SQL (0.3ms)  INSERT INTO `large_session_infos` (`session_id`, etc
 (...)
Creating new session
User: (none) from ::1 using curl 8.7.1

Now try many other requests by editing the curl command-line you can test once this has worked:

  1. Try the exact same curl command a second time. It should work bu the message in the logs should say Re-using existing session instead of Creating.
  2. Try to change the token to make it invalid
  3. Try to change the -H "Accept: text/html" to make sure CBRAIN complains
  4. Try to just remove the -d "jsonhere" part and send instead -d ""

@AviJxn
Copy link
Contributor

AviJxn commented Mar 20, 2026

This is a great addition @prioux! The JWT mechanism is a perfect fit for the CBRAIN-CLI v1.0 roadmap.

It aligns perfectly with my proposed XDG compliant config manager (~/.config/cbrain/). I can now include a schema for these shared secrets, allowing the CLI to support high security, 'headless' non interactive jobs on HPC clusters without needing raw passwords in environment variables.

I will be following the merge of #1604 closely to ensure the Lazy-Auth Interceptor I am building is fully compatible with this new endpoint!

@prioux
Copy link
Member Author

prioux commented Mar 20, 2026

@AviJxn This PR has nothing to do with the CLI client, and provides no functionality that would help the CLi client. I do not understand why you are even talking about a schema for shared secrets, given that any users of the CLI client already has a mechanism to authenticate that works perfectly well.

This PR was implemented as a feature to help out another project. Some research group is deploying the LORIS Data Query Tool, and they wanted to be able to obtain a token and let users of the DQT send data to CBRAIN. Given LORIS servers have their own user namespace, and they are deployed in environments where CORS aren't readily usable, my API entry point was pretty much the only way to provide the feature.

Please don't waste time implementing anything for the CLI related to this token mechanism. I would prefer the cli stand on its own as a traditional API client with any form of SSO.

@AviJxn
Copy link
Contributor

AviJxn commented Mar 21, 2026

Thanks for the context @prioux! I will stay away from the JWT/SSO side of things and keep the CLI focused on being a solid traditional API client.

I am shifting my focus entirely back to the v1.0 production standards we need, specifically the move to argparse for zero-dependency and the XDG config structure. I want to make sure the CLI is as robust and 'standalone' as possible for researchers using it in the field.

@natacha-beck
Copy link
Contributor

For information I needed to add :iat => Time.now.to_i when I generate the token

tok=JWT.encode( { :user_id => u.id, :client => 'loris', :iat=> Time.now.to_i}, u.get_shared_secret_for_client('loris'), 'HS256')

@prioux
Copy link
Member Author

prioux commented Mar 23, 2026

@natacha-beck Good catch, indeed I forgot about iat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Admin Features or bugs related to administrative features API API issues or Swagger description Enhancement Priority: High Security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants