API JWT Secret Rotation

Overview

The V3 API is returning and expecting several JSON Web Tokens (JWT’s) when the provided endpoints of the API are used. To prevent attacks, the JWT’s are signed with a secret that belongs to the related APP. For security reasons SECURITY-4022 we got the task to implement a periodic rotation for all non archived applications (SUITEDEV-27129).

Details

The script itself is very simple and is triggered by CRON on a daily base:

  1. CRON invokes the script

  2. The script checks if the flipper ROTATE_API_JWT_SECRET_ENABLED is set to true. If this is not the case, the script will log this and just exit.

  3. If the flipper ROTATE_API_JWT_SECRET_ENABLED is set the script

    1. queries a maximum of 10 applications where date in api_jwt_secret_expires_at is less than the actual date and the field archived_at is NULL AND

    2. does for each of the applications the following in the database

      1. update the api_jwt_secret_expires_at to now plus 6 months

      2. update the value of api_jwt_secret to a new secret

      3. update the updated date

      4. reports the update of the application via the entity-events to the me-client-service so that this service can invalidate the respective cache entry.

      5. log the success/failure of the update

Environment

The script is using the following environment variables:

  • ROTATE_API_JWT_SECRET_ENABLED: If set to exactly true the rotation will be executed (is enabled) otherwise the script will do nothing.

Artefacts

  • The script is dependent on the applications table DB entries in the push database

  • The script updates matching entries contained in the applications table DB entries in the push database

  • The script produces log entries which contain information about the success/failure of the updates.

Monitoring & Alarming

No extensions on the existing monitoring were done as error logs automatically will trigger an alarm.

Error Handling

jwt-secret-rotation-failed

If the rotation of the key for one or more APP fails, there is no real "standard procedure" which can be followed as this normally cannot not happen. If it was just a DB issue (no connection, not reachable,…​) you would not need to do anything, because the APP(s) will be picked up with the next run on the following day.

Remarks

Be careful if you think to modify the number of APPs which are taken into account for key rotation during a single day as this can heavily impact the me-client-service because all devices which use this apps need to renew the tokens.

If you want to enforce the key rotation for a specific APP you either can use the UI or you just set the date in the api_jwt_secret_expires_at DB field of the application to a date before now and you manually trigger the script.