Skip to content

Commit 75ce181

Browse files
0xi4oyau-wd
andauthored
Updates to environment and initialization logic (#5683)
* fix: make TOKEN_HASH_SECRET required and add check on server start * fix: make EXPRESS_SESSION_SECRET required and add check on server start * fix: make jwt variables required and validate on server start * fix: formatting * fix: cypress tests * fix: remove env file for cypress and refactor * revert: changes to workflow and env examples * update: how missing/weak default secrets are handled * update: how auth secrets are setup and read * fix: update env examples for docker * fix: weak defaults list * fix: weak defaults list --------- Co-authored-by: yau-wd <yau.ong@workday.com> Co-authored-by: yau-wd <246233045+yau-wd@users.noreply.github.com>
1 parent 66374bf commit 75ce181

8 files changed

Lines changed: 277 additions & 53 deletions

File tree

docker/.env.example

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ PORT=3000
44
############################################## DATABASE ####################################################
55
############################################################################################################
66

7-
DATABASE_PATH=/root/.flowise
7+
# DATABASE_PATH=/your_database_path/.flowise
88
# DATABASE_TYPE=postgres
99
# DATABASE_PORT=5432
1010
# DATABASE_HOST=""
@@ -21,20 +21,22 @@ DATABASE_PATH=/root/.flowise
2121
############################################################################################################
2222

2323
# SECRETKEY_STORAGE_TYPE=local #(local | aws)
24-
SECRETKEY_PATH=/root/.flowise
24+
# SECRETKEY_PATH=/your_secret_path/.flowise
2525
# FLOWISE_SECRETKEY_OVERWRITE=myencryptionkey # (if you want to overwrite the secret key)
2626
# SECRETKEY_AWS_ACCESS_KEY=<your-access-key>
2727
# SECRETKEY_AWS_SECRET_KEY=<your-secret-key>
2828
# SECRETKEY_AWS_REGION=us-west-2
2929
# SECRETKEY_AWS_NAME=FlowiseEncryptionKey
30+
# SECRETKEY_AWS_AUTH_PREFIX=Flowise # (when SECRETKEY_STORAGE_TYPE=aws, prefix for auth secret names e.g. FlowiseTokenHashSecret)
31+
# Auth secrets (TOKEN_HASH_SECRET, EXPRESS_SESSION_SECRET, JWT_*) can be set here or left unset to use file/AWS storage
3032

3133

3234
############################################################################################################
3335
############################################## LOGGING #####################################################
3436
############################################################################################################
3537

3638
# DEBUG=true
37-
LOG_PATH=/root/.flowise/logs
39+
# LOG_PATH=/your_log_path/.flowise/logs
3840
# LOG_LEVEL=info #(error | warn | info | verbose | debug)
3941
# LOG_SANITIZE_BODY_FIELDS=password,pwd,pass,secret,token,apikey,api_key,accesstoken,access_token,refreshtoken,refresh_token,clientsecret,client_secret,privatekey,private_key,secretkey,secret_key,auth,authorization,credential,credentials
4042
# LOG_SANITIZE_HEADER_FIELDS=authorization,x-api-key,x-auth-token,cookie
@@ -48,7 +50,7 @@ LOG_PATH=/root/.flowise/logs
4850
############################################################################################################
4951

5052
# STORAGE_TYPE=local (local | s3 | gcs)
51-
BLOB_STORAGE_PATH=/root/.flowise/storage
53+
# BLOB_STORAGE_PATH=/your_storage_path/.flowise/storage
5254
# S3_STORAGE_BUCKET_NAME=flowise
5355
# S3_STORAGE_ACCESS_KEY_ID=<your-access-key>
5456
# S3_STORAGE_SECRET_ACCESS_KEY=<your-secret-key>
@@ -91,20 +93,29 @@ BLOB_STORAGE_PATH=/root/.flowise/storage
9193
# ALLOW_UNAUTHORIZED_CERTS=false
9294
# SENDER_EMAIL=team@example.com
9395

94-
JWT_AUTH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
95-
JWT_REFRESH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
96-
JWT_ISSUER='ISSUER'
97-
JWT_AUDIENCE='AUDIENCE'
96+
# Auth secrets: set via env (backwards compat) or leave unset to use file/AWS storage (SECRETKEY_PATH or SECRETKEY_STORAGE_TYPE=aws)
97+
# Generate a secure 32-byte secret using: openssl rand -hex 32
98+
# JWT_AUTH_TOKEN_SECRET=
99+
# JWT_REFRESH_TOKEN_SECRET=
100+
101+
JWT_ISSUER=Flowise
102+
JWT_AUDIENCE=Flowise
98103
JWT_TOKEN_EXPIRY_IN_MINUTES=360
99104
JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
105+
100106
# EXPIRE_AUTH_TOKENS_ON_RESTART=true # (if you need to expire all tokens on app restart)
101-
# EXPRESS_SESSION_SECRET=flowise
107+
108+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
109+
# EXPRESS_SESSION_SECRET=
110+
102111
# SECURE_COOKIES=
103112

104113
# INVITE_TOKEN_EXPIRY_IN_HOURS=24
105114
# PASSWORD_RESET_TOKEN_EXPIRY_IN_MINS=15
106115
# PASSWORD_SALT_HASH_ROUNDS=10
107-
# TOKEN_HASH_SECRET='popcorn'
116+
117+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
118+
# TOKEN_HASH_SECRET=
108119

109120
# WORKSPACE_INVITE_TEMPLATE_PATH=/path/to/custom/workspace_invite.hbs
110121

@@ -167,7 +178,6 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
167178
# REDIS_KEEP_ALIVE=
168179
# ENABLE_BULLMQ_DASHBOARD=
169180

170-
171181
############################################################################################################
172182
############################################## SECURITY ####################################################
173183
############################################################################################################
@@ -176,3 +186,11 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
176186
# CUSTOM_MCP_SECURITY_CHECK=true
177187
# CUSTOM_MCP_PROTOCOL=sse #(stdio | sse)
178188
# TRUST_PROXY=true #(true | false | 1 | loopback| linklocal | uniquelocal | IP addresses | loopback, IP addresses)
189+
190+
191+
############################################################################################################
192+
########################################### DOCUMENT LOADERS ###############################################
193+
############################################################################################################
194+
195+
# PUPPETEER_EXECUTABLE_FILE_PATH='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
196+
# PLAYWRIGHT_EXECUTABLE_FILE_PATH='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'

docker/worker/.env.example

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ WORKER_PORT=5566
44
############################################## DATABASE ####################################################
55
############################################################################################################
66

7-
DATABASE_PATH=/root/.flowise
7+
# DATABASE_PATH=/your_database_path/.flowise
88
# DATABASE_TYPE=postgres
99
# DATABASE_PORT=5432
1010
# DATABASE_HOST=""
@@ -21,20 +21,22 @@ DATABASE_PATH=/root/.flowise
2121
############################################################################################################
2222

2323
# SECRETKEY_STORAGE_TYPE=local #(local | aws)
24-
SECRETKEY_PATH=/root/.flowise
24+
# SECRETKEY_PATH=/your_secret_path/.flowise
2525
# FLOWISE_SECRETKEY_OVERWRITE=myencryptionkey # (if you want to overwrite the secret key)
2626
# SECRETKEY_AWS_ACCESS_KEY=<your-access-key>
2727
# SECRETKEY_AWS_SECRET_KEY=<your-secret-key>
2828
# SECRETKEY_AWS_REGION=us-west-2
2929
# SECRETKEY_AWS_NAME=FlowiseEncryptionKey
30+
# SECRETKEY_AWS_AUTH_PREFIX=Flowise # (when SECRETKEY_STORAGE_TYPE=aws, prefix for auth secret names e.g. FlowiseTokenHashSecret)
31+
# Auth secrets (TOKEN_HASH_SECRET, EXPRESS_SESSION_SECRET, JWT_*) can be set here or left unset to use file/AWS storage
3032

3133

3234
############################################################################################################
3335
############################################## LOGGING #####################################################
3436
############################################################################################################
3537

3638
# DEBUG=true
37-
LOG_PATH=/root/.flowise/logs
39+
# LOG_PATH=/your_log_path/.flowise/logs
3840
# LOG_LEVEL=info #(error | warn | info | verbose | debug)
3941
# LOG_SANITIZE_BODY_FIELDS=password,pwd,pass,secret,token,apikey,api_key,accesstoken,access_token,refreshtoken,refresh_token,clientsecret,client_secret,privatekey,private_key,secretkey,secret_key,auth,authorization,credential,credentials
4042
# LOG_SANITIZE_HEADER_FIELDS=authorization,x-api-key,x-auth-token,cookie
@@ -48,7 +50,7 @@ LOG_PATH=/root/.flowise/logs
4850
############################################################################################################
4951

5052
# STORAGE_TYPE=local (local | s3 | gcs)
51-
BLOB_STORAGE_PATH=/root/.flowise/storage
53+
# BLOB_STORAGE_PATH=/your_storage_path/.flowise/storage
5254
# S3_STORAGE_BUCKET_NAME=flowise
5355
# S3_STORAGE_ACCESS_KEY_ID=<your-access-key>
5456
# S3_STORAGE_SECRET_ACCESS_KEY=<your-secret-key>
@@ -91,20 +93,29 @@ BLOB_STORAGE_PATH=/root/.flowise/storage
9193
# ALLOW_UNAUTHORIZED_CERTS=false
9294
# SENDER_EMAIL=team@example.com
9395

94-
JWT_AUTH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
95-
JWT_REFRESH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
96-
JWT_ISSUER='ISSUER'
97-
JWT_AUDIENCE='AUDIENCE'
96+
# Auth secrets: set via env (backwards compat) or leave unset to use file/AWS storage (SECRETKEY_PATH or SECRETKEY_STORAGE_TYPE=aws)
97+
# Generate a secure 32-byte secret using: openssl rand -hex 32
98+
# JWT_AUTH_TOKEN_SECRET=
99+
# JWT_REFRESH_TOKEN_SECRET=
100+
101+
JWT_ISSUER=Flowise
102+
JWT_AUDIENCE=Flowise
98103
JWT_TOKEN_EXPIRY_IN_MINUTES=360
99104
JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
105+
100106
# EXPIRE_AUTH_TOKENS_ON_RESTART=true # (if you need to expire all tokens on app restart)
101-
# EXPRESS_SESSION_SECRET=flowise
107+
108+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
109+
# EXPRESS_SESSION_SECRET=
110+
102111
# SECURE_COOKIES=
103112

104113
# INVITE_TOKEN_EXPIRY_IN_HOURS=24
105114
# PASSWORD_RESET_TOKEN_EXPIRY_IN_MINS=15
106115
# PASSWORD_SALT_HASH_ROUNDS=10
107-
# TOKEN_HASH_SECRET='popcorn'
116+
117+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
118+
# TOKEN_HASH_SECRET=
108119

109120
# WORKSPACE_INVITE_TEMPLATE_PATH=/path/to/custom/workspace_invite.hbs
110121

@@ -167,7 +178,6 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
167178
# REDIS_KEEP_ALIVE=
168179
# ENABLE_BULLMQ_DASHBOARD=
169180

170-
171181
############################################################################################################
172182
############################################## SECURITY ####################################################
173183
############################################################################################################
@@ -176,3 +186,11 @@ JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
176186
# CUSTOM_MCP_SECURITY_CHECK=true
177187
# CUSTOM_MCP_PROTOCOL=sse #(stdio | sse)
178188
# TRUST_PROXY=true #(true | false | 1 | loopback| linklocal | uniquelocal | IP addresses | loopback, IP addresses)
189+
190+
191+
############################################################################################################
192+
########################################### DOCUMENT LOADERS ###############################################
193+
############################################################################################################
194+
195+
# PUPPETEER_EXECUTABLE_FILE_PATH='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
196+
# PLAYWRIGHT_EXECUTABLE_FILE_PATH='C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'

packages/server/.env.example

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PORT=3000
2727
# SECRETKEY_AWS_SECRET_KEY=<your-secret-key>
2828
# SECRETKEY_AWS_REGION=us-west-2
2929
# SECRETKEY_AWS_NAME=FlowiseEncryptionKey
30+
# SECRETKEY_AWS_AUTH_PREFIX=Flowise # (when SECRETKEY_STORAGE_TYPE=aws, prefix for auth secret names e.g. FlowiseTokenHashSecret)
31+
# Auth secrets (TOKEN_HASH_SECRET, EXPRESS_SESSION_SECRET, JWT_*) can be set here or left unset to use file/AWS storage
3032

3133

3234
############################################################################################################
@@ -91,20 +93,29 @@ PORT=3000
9193
# ALLOW_UNAUTHORIZED_CERTS=false
9294
# SENDER_EMAIL=team@example.com
9395

94-
JWT_AUTH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
95-
JWT_REFRESH_TOKEN_SECRET='AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD'
96-
JWT_ISSUER='ISSUER'
97-
JWT_AUDIENCE='AUDIENCE'
96+
# Auth secrets: set via env (backwards compat) or leave unset to use file/AWS storage (SECRETKEY_PATH or SECRETKEY_STORAGE_TYPE=aws)
97+
# Generate a secure 32-byte secret using: openssl rand -hex 32
98+
# JWT_AUTH_TOKEN_SECRET=
99+
# JWT_REFRESH_TOKEN_SECRET=
100+
101+
JWT_ISSUER=Flowise
102+
JWT_AUDIENCE=Flowise
98103
JWT_TOKEN_EXPIRY_IN_MINUTES=360
99104
JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
105+
100106
# EXPIRE_AUTH_TOKENS_ON_RESTART=true # (if you need to expire all tokens on app restart)
101-
# EXPRESS_SESSION_SECRET=flowise
107+
108+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
109+
# EXPRESS_SESSION_SECRET=
110+
102111
# SECURE_COOKIES=
103112

104113
# INVITE_TOKEN_EXPIRY_IN_HOURS=24
105114
# PASSWORD_RESET_TOKEN_EXPIRY_IN_MINS=15
106115
# PASSWORD_SALT_HASH_ROUNDS=10
107-
# TOKEN_HASH_SECRET='popcorn'
116+
117+
# Generate a secure 32-byte secret using: openssl rand -hex 32 (or leave unset for file/AWS storage)
118+
# TOKEN_HASH_SECRET=
108119

109120
# WORKSPACE_INVITE_TEMPLATE_PATH=/path/to/custom/workspace_invite.hbs
110121

packages/server/src/enterprise/middleware/passport/index.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,21 @@ import { OrganizationUserErrorMessage, OrganizationUserService } from '../../ser
1919
import { OrganizationService } from '../../services/organization.service'
2020
import { RoleErrorMessage, RoleService } from '../../services/role.service'
2121
import { WorkspaceUserService } from '../../services/workspace-user.service'
22+
import {
23+
getExpressSessionSecret,
24+
getJWTAudience,
25+
getJWTAuthTokenSecret,
26+
getJWTIssuer,
27+
getJWTRefreshTokenSecret
28+
} from '../../utils/authSecrets'
2229
import { decryptToken, encryptToken, generateSafeCopy } from '../../utils/tempTokenUtils'
2330
import { getAuthStrategy } from './AuthStrategy'
2431
import { initializeDBClientAndStore, initializeRedisClientAndStore } from './SessionPersistance'
2532
import { v4 as uuidv4 } from 'uuid'
2633

2734
const localStrategy = require('passport-local').Strategy
2835

29-
const jwtAudience = process.env.JWT_AUDIENCE || 'AUDIENCE'
30-
const jwtIssuer = process.env.JWT_ISSUER || 'ISSUER'
31-
3236
const expireAuthTokensOnRestart = process.env.EXPIRE_AUTH_TOKENS_ON_RESTART === 'true'
33-
const jwtAuthTokenSecret = process.env.JWT_AUTH_TOKEN_SECRET || 'auth_token'
34-
const jwtRefreshSecret = process.env.JWT_REFRESH_TOKEN_SECRET || process.env.JWT_AUTH_TOKEN_SECRET || 'refresh_token'
3537

3638
// Allow explicit override of cookie security settings
3739
// This is useful when running behind a reverse proxy/load balancer that terminates SSL
@@ -46,16 +48,11 @@ const secureCookie =
4648
: process.env.APP_URL?.startsWith('https')
4749
? true
4850
: false
49-
const jwtOptions = {
50-
secretOrKey: jwtAuthTokenSecret,
51-
audience: jwtAudience,
52-
issuer: jwtIssuer
53-
}
5451

5552
const _initializePassportMiddleware = async (app: express.Application) => {
5653
// Configure session middleware
5754
let options: any = {
58-
secret: process.env.EXPRESS_SESSION_SECRET || 'flowise',
55+
secret: getExpressSessionSecret(),
5956
resave: false,
6057
saveUninitialized: false,
6158
cookie: {
@@ -101,6 +98,11 @@ const _initializePassportMiddleware = async (app: express.Application) => {
10198
export const initializeJwtCookieMiddleware = async (app: express.Application, identityManager: IdentityManager) => {
10299
await _initializePassportMiddleware(app)
103100

101+
const jwtOptions = {
102+
secretOrKey: getJWTAuthTokenSecret(),
103+
audience: getJWTAudience(),
104+
issuer: getJWTIssuer()
105+
}
104106
const strategy = getAuthStrategy(jwtOptions)
105107
passport.use(strategy)
106108
passport.use(
@@ -234,7 +236,7 @@ export const initializeJwtCookieMiddleware = async (app: express.Application, id
234236
const refreshToken = req.cookies.refreshToken
235237
if (!refreshToken) return res.sendStatus(401)
236238

237-
jwt.verify(refreshToken, jwtRefreshSecret, async (err: any, payload: any) => {
239+
jwt.verify(refreshToken, getJWTRefreshTokenSecret(), async (err: any, payload: any) => {
238240
if (err || !payload) return res.status(401).json({ message: ErrorMessage.REFRESH_TOKEN_EXPIRED })
239241
// @ts-ignore
240242
const loggedInUser = req.user as LoggedInUser
@@ -368,7 +370,7 @@ export const generateJwtAuthToken = (user: any) => {
368370
if (expiryInMinutes === -1) {
369371
expiryInMinutes = process.env.JWT_TOKEN_EXPIRY_IN_MINUTES ? parseInt(process.env.JWT_TOKEN_EXPIRY_IN_MINUTES) : 60
370372
}
371-
return _generateJwtToken(user, expiryInMinutes, jwtAuthTokenSecret)
373+
return _generateJwtToken(user, expiryInMinutes, getJWTAuthTokenSecret())
372374
}
373375

374376
export const generateJwtRefreshToken = (user: any) => {
@@ -390,17 +392,17 @@ export const generateJwtRefreshToken = (user: any) => {
390392
? parseInt(process.env.JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES)
391393
: 129600 // 90 days
392394
}
393-
return _generateJwtToken(user, expiryInMinutes, jwtRefreshSecret)
395+
return _generateJwtToken(user, expiryInMinutes, getJWTRefreshTokenSecret())
394396
}
395397

396398
const _generateJwtToken = (user: Partial<LoggedInUser>, expiryInMinutes: number, secret: string) => {
397399
const encryptedUserInfo = encryptToken(user?.id + ':' + user?.activeWorkspaceId)
398-
return sign({ id: user?.id, username: user?.name, meta: encryptedUserInfo }, secret!, {
400+
return sign({ id: user?.id, username: user?.name, meta: encryptedUserInfo }, secret, {
399401
expiresIn: expiryInMinutes + 'm', // Expiry in minutes
400402
notBefore: '0', // Cannot use before now, can be configured to be deferred.
401403
algorithm: 'HS256', // HMAC using SHA-256 hash algorithm
402-
audience: jwtAudience, // The audience of the token
403-
issuer: jwtIssuer // The issuer of the token
404+
audience: getJWTAudience(),
405+
issuer: getJWTIssuer()
404406
})
405407
}
406408

0 commit comments

Comments
 (0)