case 4711 - JWT signing key generated by the server; AYANOVA_JWT_SECRET removed

The LAN/IIS and Linux templates shipped a placeholder secret printed in the
manual, and installs that kept it signed logins with a public key; any setting
also invited short or reused values (security review F1). The setting is now
ignored (one warning at boot if still present): the server generates a key once
(48 random bytes) into jwt-signing.key in the data folder (beside the app if
there is none; owner-only on Linux) and reuses it, so sign-ins also survive a
restart where the server used to make a new key each boot (standalone, Linux
desktop). If the file cannot be used, a temporary key is used for that run.

Templates and dev launch configs drop the setting; manual updated (key page
rewritten, setting steps removed from install pages); changelog line.

Checked locally: token forged with the old placeholder 401; key file created
and reused after restart (old token 200); auth and 2FA tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 12:01:08 -07:00
parent 5bf1f2700a
commit a843bd3132
14 changed files with 61 additions and 113 deletions

View File

@@ -66,9 +66,7 @@ A User's authentication token can be [revoked at any time](adm-users.md#revoking
## Loss of authentication on server restart
If the Users are forced to re-login any time the AyaNova server is restarted the [JWT Secret setting](ops-config-jwt-secret.md) was probably not set as recommended during installation and should be verified.
If this setting is configured properly Users will be able to continue working after the server is restarted without the need to log back in again.
Users stay logged in when the AyaNova server restarts, because the server keeps its [sign-in key](ops-config-jwt-secret.md) in its data folder. If Users are forced to log in again after every restart, check the server log at startup: AyaNova notes there if it could not read or create the sign-in key file, which usually means the AyaNova server cannot write to its data folder.
## Logout

View File

@@ -19,6 +19,7 @@ IN PROGRESS
**Changed**
- Server: after several incorrect two-factor authentication codes, the password must be entered again before another code can be tried.
- Server: the `AYANOVA_JWT_SECRET` setting is no longer used. AyaNova now generates its own [sign-in key](ops-config-jwt-secret.md) once and keeps it in its data folder, so users stay logged in when the server restarts. The setting can be removed from `config.json`.
- Server: updated to use .NET 10.x LTS from previously used .NET 8.x LTS. .NET 8.x reaches end of support in November 2026. With this update to .NET 10.x come performance and security gains.
- Server: all 3rd party components used by the AyaNova server have been upgraded to their most recent release versions to use with .NET 10.x. This improves performance, stability and security for each component used.
- Server: the report rendering system now uses the smaller and faster "Chrome headless shell" browser instead of the full Chrome browser. It is downloaded into a `report-browser` folder under the AyaNova data folder instead of the program folder, so it is no longer removed by an upgrade. There will be a longer than normal delay the _first time_ a report is rendered after upgrading while AyaNova automatically downloads the new report rendering browser. Any old `Chrome` and `ChromeHeadlessShell` folders in the AyaNova program folder are no longer used and can be removed.

View File

@@ -86,7 +86,7 @@ Command line parameters are appended to the command to start the ayanova server,
### API
- [AYANOVA_JWT_SECRET](ops-config-jwt-secret.md)
- [AYANOVA_JWT_SECRET](ops-config-jwt-secret.md) (no longer used as of version 8.3.0)
- [AYANOVA_USE_URLS](ops-config-use-urls.md)
### REPORTING

View File

@@ -1,56 +1,23 @@
# JWT secret setting
# Security and JWT web tokens
AyaNova uses JSON Web Tokens (JWT) for authentication.
These time limited tokens are signed by the server using a JWT secret key and issued to users when they log in to the AyaNova server.
When a User logs in, the AyaNova server issues them a time limited token signed with the server's own sign-in key. The token is sent with every request the User makes and is verified by the server each time.
Every time the user makes a request to the server the JWT is sent along as well and verified to be valid.
Tokens expire 5 days after they are issued, and each User can only have one current token: logging in again replaces the previous one.
Tokens have a built in expiry mechanism of 5 days from issue.
(Individual Users can be prevented from logging in or accessing the server by [setting them inactive](adm-users.md#revoking-access-and-locking-out-users), which takes effect immediately regardless of how many days are left on their current token.)
All active tokens previously issued can be invalidated by changing this JWT Secret setting and restarting the server (or restarting the server and allowing it to choose a new secret value randomly if none is specified).
## The sign-in key
(Individual Users can be prevented from logging in or accessing the server by setting them inactive which takes effect immediately regardless of how many days are left on their current access token.)
The AyaNova server generates its sign-in key automatically the first time it starts and keeps it in a file named `jwt-signing.key` in the AyaNova [data folder](ops-config-data-path.md). It is used from then on, so Users stay logged in when the server restarts. There is nothing to configure.
## Default
Keep the data folder protected like the rest of AyaNova's data: anyone who can read the sign-in key file could create valid tokens.
If no secret key is specified the server will generate a new, random one each time it starts and this means that remote users who previously authenticated will need to login freshly if the server is restarted.
## Signing everyone out
If you would like to ensure that a server reboot does not affect remote users credentials then you can specify a value for the secret key so that the same key will always be used by the server even if it reboots.
## Overriding
AyaNova expects the JWT secret to be provided by a config.json property, environment variable or command line parameter named
`AYANOVA_JWT_SECRET`
The value specified should be a string of up to 32 characters, for example:
`02847This_is_my_secret_key456576`
If fewer than 32 characters are provided they secret will be padded out to 32 characters. If more than 32 characters are specified it will only use the first 32.
You should use the same precautions as for choosing any other password and ensure the secret is not well known or easily looked up in a dictionary. 32 random characters would be sufficient.
Example config.json entry
```json
{
...other properties...
"AYANOVA_JWT_SECRET": "My32CharacterSecretKey0123456789"
}
```
Example command line parameter
`ayanova.exe --AYANOVA_JWT_SECRET="02847This_is_my_secret_key456576"`
Example environment variable
Windows
`set "AYANOVA_JWT_SECRET=02847This_is_my_secret_key456576"`
Linux
`export AYANOVA_JWT_SECRET="02847This_is_my_secret_key456576"`
To invalidate every token that has been issued (for example if you suspect a token or the key file was exposed): stop the AyaNova server, delete the `jwt-signing.key` file from the data folder, and start the server again. A new key is generated and every User will need to log in again.
## AYANOVA_JWT_SECRET (no longer used)
Before version 8.3.0 the sign-in key could be set with an `AYANOVA_JWT_SECRET` configuration setting. That setting is no longer used: if it is still present in config.json, an environment variable or the command line it is ignored, a note is written to the server log, and it can safely be removed.

View File

@@ -197,16 +197,6 @@ The [AYANOVA_DB_CONNECTION](ops-config-db.md) property must be edited and where
The [AYANOVA_USE_URLS](ops-config-use-urls.md) property specifies which TCP / IP Port that AyaNova server should listen on for connections from web browsers. The default value is port 7575 which should be free in most cases, however if you need to use an alternate port due to conflict it must be set here. We recommend using the default 7575 to avoid current or future confusion or conflict with other servers that may be installed or present elsewhere on the network.
Optional but recommended: Add a 32 character [AYANOVA_JWT_SECRET](ops-config-jwt-secret.md) property to the configuration if you want to ensure that logged in User's session can survive a restart of the AyaNova server. If this is not set AyaNova will invalidate all login tokens any time the server restarts by generating a new random JWT secret on boot.
```json
{
...existing properties...
"AYANOVA_LOG_LEVEL": "Info",
"AYANOVA_JWT_SECRET": "1111111MyRandom32CharacterSecret"
}
```
Edit the config.json file in your favorite editor, here we'll use Nano:
```bash

View File

@@ -232,20 +232,6 @@ The [AYANOVA_BACKUP_PG_DUMP_PATH](ops-config-backup-pgdump-path.md) property spe
A. if AyaNova server will be doing the automatic daily backups using AyaNova's Backup feature, confirm this path stated matches the path to YOUR PostgreSQL database backup utility pg_dump. The `18` in the path is the PostgreSQL version number: if you installed a different version, change it to match (for example `C:\\Program Files\\PostgreSQL\\17\\bin`)
B. otherwise, If you already have a backup solution in place for your PostgreSQL databases AND WILL NOT BE USING AYANOVA'S Backup feature, remove this
OPTIONAL EDIT:
Modify the 32 character [AYANOVA_JWT_SECRET](ops-config-jwt-secret.md) property of the configuration which ensures that the logged in User's session can survive a restart of the AyaNova server. If this is not set AyaNova will invalidate all login tokens any time the server restarts by generating a new random JWT secret on boot which under IIS happens frequently.
Change this from the default of "11111YourRandom32CharacterSecret" to be unique to your site (must be 32 characters).
```json
{
...existing properties...
"AYANOVA_LOG_LEVEL": "Info",
"AYANOVA_JWT_SECRET": "11111YourRandom32CharacterSecret"
}
```
After editing, saving and exiting out of NotePad, open the config.json file AGAIN to confirm that the changes were saved correctly and that the file is still specifically labeled with the name and extension config.json
### 6\. Boot and test the server

View File

@@ -164,20 +164,6 @@ The [AYANOVA_BACKUP_PG_DUMP_PATH](ops-config-backup-pgdump-path.md) property spe
A. if AyaNova server will be doing the automatic daily backups using AyaNova's Backup feature, confirm this path stated matches the path to YOUR PostgreSQL database backup utility pg_dump. The `18` in the path is the PostgreSQL version number: if you installed a different version, change it to match (for example `C:\\Program Files\\PostgreSQL\\17\\bin`)
B. otherwise, If you already have a backup solution in place for your PostgreSQL databases AND WILL NOT BE USING AYANOVA'S Backup feature, remove this
OPTIONAL EDIT:
Modify the 32 character [AYANOVA_JWT_SECRET](ops-config-jwt-secret.md) property of the configuration which ensures that the logged in User's session can survive a restart of the AyaNova server. If this is not set AyaNova will invalidate all login tokens any time the server restarts by generating a new random JWT secret on boot.
Change this from the default of "11111YourRandom32CharacterSecret" to be unique to your site (must be 32 characters).
```json
{
...existing properties...
"AYANOVA_LOG_LEVEL": "Info",
"AYANOVA_JWT_SECRET": "11111YourRandom32CharacterSecret"
}
```
After editing, saving and exiting out of NotePad, open the config.json file AGAIN to confirm that the changes were saved correctly and that the file is still specifically labeled with the name and extension config.json
### 5\. Boot and test the server