Hi Yogesh,
Please find the attached config file which we are using .
The issue which we are facing is exactly the same as it is described in
this thread
<https://github.com/pgadmin-org/pgadmin4/issues/5567#issuecomment-1508777189>
and my team member Eoghan also commented on the same.

Below are the parameters that were modified according to our needs , rest
were all the same default values only.

 # Number of values to trust for X-Forwarded-For

PROXY_X_FOR_COUNT = 1

 # Number of values to trust for X-Forwarded-Proto.

PROXY_X_PROTO_COUNT = 1

 # Number of values to trust for X-Forwarded-Host.

PROXY_X_HOST_COUNT = 1

 # Number of values to trust for X-Forwarded-Port.

PROXY_X_PORT_COUNT = 0

 # Number of values to trust for X-Forwarded-Prefix.

PROXY_X_PREFIX_COUNT = 0


USER_INACTIVITY_TIMEOUT = 900

ENHANCED_COOKIE_PROTECTION = False



Regards,
Arun

On Tue, Apr 18, 2023 at 7:23 AM Dave Page <dp...@pgadmin.org> wrote:

>
>
> On Tue, 18 Apr 2023 at 12:08, Yogesh Mahajan <
> yogesh.maha...@enterprisedb.com> wrote:
>
>> Hi,
>>
>> Could you please share your pgAdmin config setting?
>>
>
> FYI, the /misc/ping endpoint is CSRF-exempt.
>
>
>>
>> Thanks,
>> Yogesh Mahajan
>> EnterpriseDB
>>
>>
>> On Fri, Apr 14, 2023 at 8:45 PM Aruna Manivannan <
>> aruna.manivan...@gmail.com> wrote:
>>
>>> Hi Yogesh,
>>> Thanks for your reply. Please find the attached log file. The log
>>> entries keep repeating so given the portion of them.
>>> Sending it to you alone due to security reasons.
>>> FYI we have the parameter ENHANCED_COOKIE_PROTECTION = false to avoid
>>> CSRF token issue, but it seems to be ignored.
>>> Thanks.
>>>
>>>
>>> Regards,
>>> Arun
>>>
>>> On Fri, Apr 14, 2023 at 5:33 AM Yogesh Mahajan <
>>> yogesh.maha...@enterprisedb.com> wrote:
>>>
>>>> Hi,
>>>>
>>>> Could you please complete the logs from the container? I suspect those
>>>> errors are because of CSRF token errors.
>>>>
>>>>
>>>> Thanks,
>>>> Yogesh Mahajan
>>>> EnterpriseDB
>>>>
>>>>
>>>> On Thu, Apr 13, 2023 at 11:04 PM Aruna Manivannan <
>>>> aruna.manivan...@gmail.com> wrote:
>>>>
>>>>> Hi Yogesh / pgadmin-support team,
>>>>> Have set up the liveness probe as suggested by you. However, It is now
>>>>> super helpful. The problem I am facing is though the /misc/ping is giving
>>>>> 200 status, I received complaints from users that they cant access 
>>>>> pgadmin.
>>>>> When I checked the logs, I noticed that /sqleditor/status/<some
>>>>> number> is 500 & 503. I guess the number could be session ID or something
>>>>> not sure. Please find the below log message
>>>>>
>>>>> [::ffff:<private_ip_address> - - [13/Apr/2023:16:28:13 +0000] "GET
>>>>> /misc/ping HTTP/1.1" 200 4 "-" "kube-probe/1.24+"
>>>>> ::ffff:<private_ip_address> - - [13/Apr/2023:16:28:13 +0000] "GET
>>>>> /misc/ping HTTP/1.1" 200 4 "-" "kube-probe/1.24+"
>>>>> <public_ip_address> - - [13/Apr/2023:16:28:14 +0000] "GET
>>>>> /sqleditor/status/4397343 HTTP/1.1" 500 103 "
>>>>> https://pgadmin-url/sqleditor/panel/4397343?is_query_tool=true&sgid=96&sid=307&did=<db_id>&database_name=<db_name>"
>>>>> "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101
>>>>> Firefox/112.0"
>>>>> <public_ip_address> - - [13/Apr/2023:16:28:14 +0000] "GET
>>>>> /sqleditor/status/9414096 HTTP/1.1" 503 100 "
>>>>> https://pgadmin-url/sqleditor/panel/9414096?is_query_tool=true&sgid=96&sid=307&did=<db_id>&database_name=<db_name>"
>>>>> "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101
>>>>> Firefox/112.0"
>>>>> <public_ip_address> - - [13/Apr/2023:16:28:14 +0000] "GET
>>>>> /sqleditor/status/9414096 HTTP/1.1" 503 100 "
>>>>> https://pgadmin-url/sqleditor/panel/9414096?is_query_tool=true&sgid=96&sid=307&did=<db_id>&database_name=<db_name>"
>>>>> "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101
>>>>> Firefox/112.0"
>>>>> <public_ip_address> - - [13/Apr/2023:16:28:14 +0000] "GET
>>>>> /sqleditor/status/9414096 HTTP/1.1" 503 100 "
>>>>> https://pgadmin-url/sqleditor/panel/9414096?is_query_tool=true&sgid=96&sid=307&did=<db_id>&database_name=<db_name>"
>>>>> "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101
>>>>> Firefox/112.0
>>>>>
>>>>> Later I restarted the pgadmin pod to get rid of this issue. Could you
>>>>> please explain what exactly is happening and how to fix it ? Thanks.
>>>>>
>>>>> Regards,
>>>>> Arun
>>>>>
>>>>> On Tue, Apr 11, 2023 at 10:42 AM Aruna Manivannan <
>>>>> aruna.manivan...@gmail.com> wrote:
>>>>>
>>>>>> Hi Yogesh,
>>>>>> Thanks for your response. Will use it and let you know the result.
>>>>>> Thank you again.
>>>>>>
>>>>>> Regards,
>>>>>> Arun
>>>>>>
>>>>>> On Tue, Apr 11, 2023 at 1:58 AM Yogesh Mahajan <
>>>>>> yogesh.maha...@enterprisedb.com> wrote:
>>>>>>
>>>>>>> Hi Aruna,
>>>>>>>
>>>>>>> You can use 'misc/ping' to monitor health checks.
>>>>>>> E.g.
>>>>>>>
>>>>>>> pgadmin:
>>>>>>>     image: dpage/pgadmin4
>>>>>>>     healthcheck:
>>>>>>>       test: ["CMD", "wget", "-O", "-", "http://localhost:80/misc/ping";]
>>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Yogesh Mahajan
>>>>>>> EnterpriseDB
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Apr 11, 2023 at 2:20 AM Aruna Manivannan <
>>>>>>> aruna.manivan...@gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi Team,
>>>>>>>> This is Arun. Could you please help me with setting up a Liveness &
>>>>>>>> Readiness probe for pgadmin4 6.17 which is running in the Kubernetes
>>>>>>>> cluster as Statefulset. I mean, is there any URL endpoint which I can
>>>>>>>> configure to hit? Thanks.
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Arun
>>>>>>>>
>>>>>>>
>
> --
> Dave Page
> Blog: https://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EDB: https://www.enterprisedb.com
>
>
config.py:
#
# -*- coding: utf-8 -*-
 ##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2023, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
# config.py - Core application configuration settings
#
##########################################################################
import builtins
import logging
import os
import sys
# We need to include the root directory in sys.path to ensure that we can
# find everything we need when running in the standalone runtime.
root = os.path.dirname(os.path.realpath(__file__))
if sys.path[0] != root:
    sys.path.insert(0, root)
 from pgadmin.utils import env, IS_WIN, fs_short_path
 ##########################################################################
# Application settings
##########################################################################
 # Name of the application to display in the UI
APP_NAME = 'pgAdmin 4'
APP_ICON = 'pg-icon'
 ##########################################################################
# Application settings
##########################################################################
 # NOTE!!!
# If you change any of APP_RELEASE, APP_REVISION or APP_SUFFIX, then you
# must also change APP_VERSION_INT to match.
#
 # Application version number components
APP_RELEASE = 6
APP_REVISION = 17
 # Application version suffix, e.g. 'beta1', 'dev'. Usually an empty string
# for GA releases.
APP_SUFFIX = ''
 # Numeric application version for upgrade checks. Should be in the format:
# [X]XYYZZ, where X is the release version, Y is the revision, with a leading
# zero if needed, and Z represents the suffix, with a leading zero if needed
APP_VERSION_INT = 61700
 # DO NOT CHANGE!
# The application version string, constructed from the components
if not APP_SUFFIX:
    APP_VERSION = '%s.%s' % (APP_RELEASE, APP_REVISION)
else:
    APP_VERSION = '%s.%s-%s' % (APP_RELEASE, APP_REVISION, APP_SUFFIX)
 # Copyright string for display in the app
APP_COPYRIGHT = 'Copyright (C) 2013 - 2023, The pgAdmin Development Team'
 ##########################################################################
# Misc stuff
##########################################################################
 # Path to the online help.
HELP_PATH = '../../../docs/en_US/_build/html/'
 # Languages we support in the UI
LANGUAGES = {
    'en': 'English',
    'zh': 'Chinese (Simplified)',
    'cs': 'Czech',
    'fr': 'French',
    'de': 'German',
    'it': 'Italian',
    'ja': 'Japanese',
    'ko': 'Korean',
    'pl': 'Polish',
    'pt_BR': 'Portuguese (Brazilian)',
    'ru': 'Russian',
    'es': 'Spanish',
}
 # DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING!
# List of modules to skip when dynamically loading
MODULE_BLACKLIST = ['test']
 # DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING!
# List of treeview browser nodes to skip when dynamically loading
NODE_BLACKLIST = []
 ##########################################################################
# Server settings
##########################################################################
 # The server mode determines whether or not we're running on a web server
# requiring user authentication, or desktop mode which uses an automatic
# default login.
#
# DO NOT DISABLE SERVER MODE IF RUNNING ON A WEBSERVER!!
#
# We only set SERVER_MODE if it's not already set. That's to allow the
# runtime to force it to False.
#
# NOTE: If you change the value of SERVER_MODE or DATA_DIR in an included
#       config file, you may also need to redefine any values below that are
#       derived from it, notably various paths such as LOG_FILE, SQLITE_PATH,
#       SESSION_DB_PATH, STORAGE_DIR, KERBEROS_CCACHE_DIR, and
#       AZURE_CREDENTIAL_CACHE_DIR
 if (not hasattr(builtins, 'SERVER_MODE')) or builtins.SERVER_MODE is None:
    SERVER_MODE = True
else:
    SERVER_MODE = builtins.SERVER_MODE
 # HTTP headers to search for CSRF token when it is not provided in the form.
# Default is ['X-CSRFToken', 'X-CSRF-Token']
WTF_CSRF_HEADERS = ['X-pgA-CSRFToken']
 # User ID (email address) to use for the default user in desktop mode.
# The default should be fine here, as it's not exposed in the app.
DESKTOP_USER = 'pgadm...@pgadmin.org'
 # This option allows the user to host the application on a LAN
# Default hosting is on localhost (DEFAULT_SERVER='localhost').
# To host pgAdmin4 over LAN set DEFAULT_SERVER='0.0.0.0' (or a specific
# adaptor address.
#
# NOTE: This is NOT recommended for production use, only for debugging
# or testing. Production installations should be run as a WSGI application
# behind Apache HTTPD.
DEFAULT_SERVER = '127.0.0.1'
 # The default port on which the app server will listen if not set in the
# environment by the runtime
DEFAULT_SERVER_PORT = 5050
 # This param is used to override the default web server information about
# the web technology and the frameworks being used in the application
# An attacker could use this information to fingerprint underlying operating
# system and research known exploits for the specific version of
# software in use
WEB_SERVER = 'Python'
 # Enable X-Frame-Option protection.
# Set to one of "SAMEORIGIN", "ALLOW-FROM origin" or "" to disable.
# Note that "DENY" is NOT supported (and will be silently ignored).
# See https://tools.ietf.org/html/rfc7034 for more info.
X_FRAME_OPTIONS = "SAMEORIGIN"
 # The Content-Security-Policy header allows you to restrict how resources
# such as JavaScript, CSS, or pretty much anything that the browser loads.
# see https://content-security-policy.com/#source_list for more info
# e.g. "default-src https: data: 'unsafe-inline' 'unsafe-eval';"
CONTENT_SECURITY_POLICY = "default-src ws: http: data: blob: 'unsafe-inline'" \
                          " 'unsafe-eval';"
 # STRICT_TRANSPORT_SECURITY_ENABLED when set to True will set the
# Strict-Transport-Security header
STRICT_TRANSPORT_SECURITY_ENABLED = False
 # The Strict-Transport-Security header tells the browser to convert all HTTP
# requests to HTTPS, preventing man-in-the-middle (MITM) attacks.
# e.g. 'max-age=31536000; includeSubDomains'
STRICT_TRANSPORT_SECURITY = "max-age=31536000; includeSubDomains"
 # The X-Content-Type-Options header forces the browser to honor the response
# content type instead of trying to detect it, which can be abused to
# generate a cross-site scripting (XSS) attack.
# e.g. nosniff
X_CONTENT_TYPE_OPTIONS = "nosniff"
 # The browser will try to prevent reflected XSS attacks by not loading the
# page if the request contains something that looks like JavaScript and the
# response contains the same data. e.g. '1; mode=block'
X_XSS_PROTECTION = "1; mode=block"
 # This param is used to validate ALLOWED_HOSTS for the application
# This will be used to avoid Host Header Injection attack
# ALLOWED_HOSTS = ['225.0.0.0/8', '226.0.0.0/7', '228.0.0.0/6']
# ALLOWED_HOSTS = ['127.0.0.1', '192.168.0.1']
# if ALLOWED_HOSTS= [] then it will accept all ips (and application will be
# vulnerable to Host Header Injection attack)
ALLOWED_HOSTS = []
 # Hashing algorithm used for password storage
SECURITY_PASSWORD_HASH = 'pbkdf2_sha512'
 # Reverse Proxy parameters
# You must tell the middleware how many proxies set each header
# so it knows what values to trust.
# See https://tinyurl.com/yyg7r9av
# for more information.
 # Number of values to trust for X-Forwarded-For
PROXY_X_FOR_COUNT = 1
 # Number of values to trust for X-Forwarded-Proto.
PROXY_X_PROTO_COUNT = 1
 # Number of values to trust for X-Forwarded-Host.
PROXY_X_HOST_COUNT = 1
 # Number of values to trust for X-Forwarded-Port.
PROXY_X_PORT_COUNT = 0
 # Number of values to trust for X-Forwarded-Prefix.
PROXY_X_PREFIX_COUNT = 0
 # NOTE: CSRF_SESSION_KEY, SECRET_KEY and SECURITY_PASSWORD_SALT are no
#       longer part of the main configuration, but are stored in the
#       configuration databases 'keys' table and are auto-generated.
 # COMPRESSION
COMPRESS_MIMETYPES = [
    'text/html', 'text/css', 'text/xml', 'application/json',
    'application/javascript'
]
COMPRESS_LEVEL = 9
COMPRESS_MIN_SIZE = 500
 # Set the cache control max age for static files in flask to 1 year
SEND_FILE_MAX_AGE_DEFAULT = 31556952
 # This will be added to static urls as url parameter with value as
# APP_VERSION_INT for cache busting on version upgrade. If the value is set as
# None or empty string then it will not be added.
# eg - http:localhost:5050/pgadmin.css?intver=3.13
APP_VERSION_PARAM = 'ver'
 # Add the internal version param to below extensions only
APP_VERSION_EXTN = ('.css', '.js', '.html', '.svg', '.png', '.gif', '.ico')
 # Data directory for storage of config settings etc. This shouldn't normally
# need to be changed - it's here as various other settings depend on it.
# On Windows, we always store data in %APPDATA%\pgAdmin. On other platforms,
# if we're in server mode we use /var/lib/pgadmin, otherwise ~/.pgadmin
if IS_WIN:
    # Use the short path on windows
    DATA_DIR = os.path.realpath(
        os.path.join(fs_short_path(env('APPDATA')), "pgAdmin")
    )
else:
    if SERVER_MODE:
        DATA_DIR = '/var/lib/pgadmin'
    else:
        DATA_DIR = os.path.realpath(os.path.expanduser('~/.pgadmin/'))
 # An optional login banner to show security warnings/disclaimers etc. at
# login and password recovery etc. HTML may be included for basic formatting,
# For example:
# LOGIN_BANNER = "<h4>Authorised Users Only!</h4>" \
#                "Unauthorised use is strictly forbidden."
LOGIN_BANNER = ""
 ##########################################################################
# Log settings
##########################################################################
 # Debug mode?
DEBUG = False
 # Application log level - one of:
#   CRITICAL 50
#   ERROR    40
#   WARNING  30
#   SQL      25
#   INFO     20
#   DEBUG    10
#   NOTSET    0
CONSOLE_LOG_LEVEL = logging.WARNING
FILE_LOG_LEVEL = logging.WARNING
 # Log format.
CONSOLE_LOG_FORMAT = '%(asctime)s: %(levelname)s\t%(name)s:\t%(message)s'
FILE_LOG_FORMAT = '%(asctime)s: %(levelname)s\t%(name)s:\t%(message)s'
 # Log file name. This goes in the data directory, except on non-Windows
# platforms in server mode.
if SERVER_MODE and not IS_WIN:
    LOG_FILE = '/var/log/pgadmin/pgadmin4.log'
else:
    LOG_FILE = os.path.join(DATA_DIR, 'pgadmin4.log')
 # Log rotation setting
# Log file will be rotated considering values for LOG_ROTATION_SIZE
# & LOG_ROTATION_AGE. Rotated file will be named in format
# - LOG_FILE.Y-m-d_H-M-S
LOG_ROTATION_SIZE = 10  # In MBs
LOG_ROTATION_AGE = 1440  # In minutes
LOG_ROTATION_MAX_LOG_FILES = 90  # Maximum number of backups to retain
##########################################################################
# Server Connection Driver Settings
##########################################################################
 # The default driver used for making connection with PostgreSQL
PG_DEFAULT_DRIVER = 'psycopg2'
 # Maximum allowed idle time in minutes before which releasing the connection
# for the particular session. (in minutes)
MAX_SESSION_IDLE_TIME = 60
 ##########################################################################
# External Database Settings
#
# All configuration settings are stored by default in the SQLite database.
# In order to use external databases like PostgreSQL sets the value of
# CONFIG_DATABASE_URI like below:
# dialect+driver://username:password@host:port/database
#
# PostgreSQL:
# postgresql://username:password@host:port/database
# Specify Schema Name
# 
postgresql://username:password@host:port/database?options=-csearch_path=pgadmin
# Using PGPASS file
# postgresql://username@host:port?options=-csearch_path=pgadmin
##########################################################################
CONFIG_DATABASE_URI = ''
 ##########################################################################
# User account and settings storage
##########################################################################
 # The default path to the SQLite database used to store user accounts and
# settings. This default places the file in the same directory as this
# config file, but generates an absolute path for use througout the app.
SQLITE_PATH = env('SQLITE_PATH') or os.path.join(DATA_DIR, 'pgadmin4.db')
 # SQLITE_TIMEOUT will define how long to wait before throwing the error -
# OperationError due to database lock. On slower system, you may need to change
# this to some higher value.
# (Default: 500 milliseconds)
SQLITE_TIMEOUT = 500
 # Allow database connection passwords to be saved if the user chooses.
# Set to False to disable password saving.
ALLOW_SAVE_PASSWORD = True
 # Maximum number of history queries stored per user/server/database
MAX_QUERY_HIST_STORED = 20
 ##########################################################################
# Server-side session storage path
#
# SESSION_DB_PATH (Default: $HOME/.pgadmin4/sessions)
##########################################################################
#
# We use SQLite for server-side session storage. There will be one
# SQLite database object per session created.
#
# Specify the path used to store your session objects.
#
# If the specified directory does not exist, the setup script will create
# it with permission mode 700 to keep the session database secure.
#
# On certain systems, you can use shared memory (tmpfs) for maximum
# scalability, for example, on Ubuntu:
#
# SESSION_DB_PATH = '/run/shm/pgAdmin4_session'
#
##########################################################################
SESSION_DB_PATH = os.path.join(DATA_DIR, 'sessions')
SESSION_COOKIE_NAME = 'pga4_session'
 ##########################################################################
# Mail server settings
##########################################################################
 # These settings are used when running in web server mode for confirming
# and resetting passwords etc.
# See: http://pythonhosted.org/Flask-Mail/ for more info
MAIL_SERVER = 'localhost'
MAIL_PORT = 25
MAIL_USE_SSL = False
MAIL_USE_TLS = False
MAIL_USERNAME = ''
MAIL_PASSWORD = ''
MAIL_DEBUG = False
 # Flask-Security overrides Flask-Mail's MAIL_DEFAULT_SENDER setting, so
# that should be set as such:
SECURITY_EMAIL_SENDER = 'no-reply@localhost'
 ##########################################################################
# Mail content settings
##########################################################################
 # These settings define the content of password reset emails
SECURITY_EMAIL_SUBJECT_PASSWORD_RESET = "Password reset instructions for %s" \
                                        % APP_NAME
SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE = "Your %s password has been reset" \
                                        % APP_NAME
SECURITY_EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE = \
    "Your password for %s has been changed" % APP_NAME
 ##########################################################################
# Email address validation
##########################################################################
 # flask-security-too will validate email addresses and check deliverability
# by default. Disable the deliverability check by default, which was the old
# behaviour in <= v5.3
CHECK_EMAIL_DELIVERABILITY = False
SECURITY_EMAIL_VALIDATOR_ARGS = \
    {"check_deliverability": CHECK_EMAIL_DELIVERABILITY}
 ##########################################################################
# Upgrade checks
##########################################################################
 # Check for new versions of the application?
UPGRADE_CHECK_ENABLED = True
 # Where should we get the data from?
UPGRADE_CHECK_URL = 'https://www.pgadmin.org/versions.json'
 # What key should we look at in the upgrade data file?
UPGRADE_CHECK_KEY = 'pgadmin4'
 # Which CA file should we use?
# Default to cacert.pem in the same directory as config.py et al.
CA_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                      "cacert.pem")
 # Check if the detected browser is supported
CHECK_SUPPORTED_BROWSER = True
 ##########################################################################
# Storage Manager storage url config settings
# If user sets STORAGE_DIR to empty it will show all volumes if platform
# is Windows, '/' if it is Linux, Mac or any other unix type system.
 # For example:
# 1. STORAGE_DIR = get_drive("C") or get_drive() # return C:/ by default
# where C can be any drive character such as "D", "E", "G" etc
# 2. Set path manually like
# STORAGE_DIR = "/path/to/directory/"
##########################################################################
STORAGE_DIR = os.path.join(DATA_DIR, 'storage')
 ##########################################################################
# Default locations for binary utilities (pg_dump, pg_restore etc)
#
# These are intentionally left empty in the main config file, but are
# expected to be overridden by packagers in config_distro.py.
#
# A default location can be specified for each database driver ID, in
# a dictionary. Either an absolute or relative path can be specified.
#
# Version-specific defaults can also be specified, which will take priority
# over un-versioned paths.
#
# In cases where it may be difficult to know what the working directory
# is, "$DIR" can be specified. This will be replaced with the path to the
# top-level pgAdmin4.py file. For example, on macOS we might use:
#
# $DIR/../../SharedSupport
#
##########################################################################
DEFAULT_BINARY_PATHS = {
    "pg": "",
    "pg-10": "",
    "pg-11": "",
    "pg-12": "",
    "pg-13": "",
    "pg-14": "",
    "pg-15": "",
    "ppas": "",
    "ppas-10": "",
    "ppas-11": "",
    "ppas-12": "",
    "ppas-13": "",
    "ppas-14": "",
    "ppas-15": ""
}
 ##########################################################################
# Test settings - used primarily by the regression suite, not for users
##########################################################################
 # The default path for SQLite database for testing
TEST_SQLITE_PATH = os.path.join(DATA_DIR, 'test_pgadmin4.db')
 ##########################################################################
# Allows flask application to response to the each request asynchronously
##########################################################################
THREADED_MODE = True
 ##########################################################################
# Do not allow SQLALCHEMY to track modification as it is going to be
# deprecated in future
##########################################################################
SQLALCHEMY_TRACK_MODIFICATIONS = False
 ##########################################################################
# Number of records to fetch in one batch in query tool when query result
# set is large.
##########################################################################
ON_DEMAND_RECORD_COUNT = 1000
 ##########################################################################
# Allow users to display Gravatar image for their username in Server mode
##########################################################################
SHOW_GRAVATAR_IMAGE = True
 ##########################################################################
# Set cookie path and options
##########################################################################
COOKIE_DEFAULT_PATH = '/'
COOKIE_DEFAULT_DOMAIN = None
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_HTTPONLY = True
 #########################################################################
# Skip storing session in files and cache for specific paths
#########################################################################
SESSION_SKIP_PATHS = [
    '/misc/ping'
]
 ##########################################################################
# Session expiration support
##########################################################################
# SESSION_EXPIRATION_TIME is the interval in Days. Session will be
# expire after the specified number of *days*.
SESSION_EXPIRATION_TIME = 1
 # Make SESSION_EXPIRATION_TIME to 1 week in DESKTOP mode
if not SERVER_MODE:
    SESSION_EXPIRATION_TIME = 7
 # CHECK_SESSION_FILES_INTERVAL is interval in Hours. Application will check
# the session files for cleanup after specified number of *hours*.
CHECK_SESSION_FILES_INTERVAL = 24
 # USER_INACTIVITY_TIMEOUT is interval in Seconds. If the pgAdmin screen is left
# unattended for <USER_INACTIVITY_TIMEOUT> seconds then the user will
# be logged out. When set to 0, the timeout will be disabled.
# If pgAdmin doesn't detect any activity in the time specified (in seconds),
# the user will be forcibly logged out from pgAdmin. Set to zero to disable
# the timeout.
# Note: This is applicable only for SERVER_MODE=True.
USER_INACTIVITY_TIMEOUT = 0
 # OVERRIDE_USER_INACTIVITY_TIMEOUT when set to True will override
# USER_INACTIVITY_TIMEOUT when long running queries in the Query Tool
# or Debugger are running. When the queries complete, the inactivity timer
# will restart in this case. If set to False, user inactivity may cause
# transactions or in-process debugging sessions to be aborted.
OVERRIDE_USER_INACTIVITY_TIMEOUT = True
 ##########################################################################
# SSH Tunneling supports only for Python 2.7 and 3.4+
##########################################################################
SUPPORT_SSH_TUNNEL = True
# Allow SSH Tunnel passwords to be saved if the user chooses.
# Set to False to disable password saving.
ALLOW_SAVE_TUNNEL_PASSWORD = False
 ##########################################################################
# Master password is used to encrypt/decrypt saved server passwords
# Applicable for desktop mode only
##########################################################################
MASTER_PASSWORD_REQUIRED = True
 ##########################################################################
# Allows pgAdmin4 to create session cookies based on IP address, so even
# if a cookie is stolen, the attacker will not be able to connect to the
# server using that stolen cookie.
# Note: This can cause problems when the server is deployed in dynamic IP
# address hosting environments, such as Kubernetes or behind load
# balancers. In such cases, this option should be set to False.
##########################################################################
ENHANCED_COOKIE_PROTECTION = True
 ##########################################################################
# External Authentication Sources
##########################################################################
 # Default setting is internal
# External Supported Sources: ldap, kerberos, oauth2
# Multiple authentication can be achieved by setting this parameter to
# ['ldap', 'internal'] or ['oauth2', 'internal'] or
# ['webserver', 'internal'] etc.
# pgAdmin will authenticate the user with ldap/oauth2 whatever first in the
# list, in case of failure the second authentication option will be considered.
 AUTHENTICATION_SOURCES = ['oauth2','internal']
 ##########################################################################
# MAX_LOGIN_ATTEMPTS which sets the number of failed login attempts that
# are allowed. If this value is exceeded the account is locked and can be
# reset by an administrator. By setting the variable to the value zero
# this feature is deactivated.
##########################################################################
MAX_LOGIN_ATTEMPTS = 3
 ##########################################################################
# Only consider password to check the failed login attempts, email is
# excluded from this check
LOGIN_ATTEMPT_FIELDS = ['password']
##########################################################################
# LDAP Configuration
##########################################################################
 # After ldap authentication, user will be added into the SQLite database
# automatically, if set to True.
# Set it to False, if user should not be added automatically,
# in this case Admin has to add the user manually in the SQLite database.
LDAP_AUTO_CREATE_USER = True
 # Connection timeout
LDAP_CONNECTION_TIMEOUT = 10
 # Server connection details (REQUIRED)
# example: ldap://<ip-address>:<port> or ldap://<hostname>:<port>
LDAP_SERVER_URI = 'ldap://<ip-address>:<port>'
 # The LDAP attribute containing user names. In OpenLDAP, this may be 'uid'
# whilst in AD, 'sAMAccountName' might be appropriate. (REQUIRED)
LDAP_USERNAME_ATTRIBUTE = '<User-id>'
 ##########################################################################
# 3 ways to configure LDAP as follows (Choose anyone):
 # 1. Dedicated User binding
 # LDAP Bind User DN Example: cn=username,dc=example,dc=com
# Set this parameter to allow the connection to bind using a dedicated user.
# After the connection is made, the pgadmin login user will be further
# authenticated by the username and password provided
# at the login screen.
LDAP_BIND_USER = None
 # LDAP Bind User Password
LDAP_BIND_PASSWORD = None
 # OR ####################
# 2. Anonymous Binding
 # Set this parameter to allow the anonymous bind.
# After the connection is made, the pgadmin login user will be further
# authenticated by the username and password provided
 LDAP_ANONYMOUS_BIND = False
 # OR ####################
# 3. Bind as pgAdmin user
 # BaseDN (REQUIRED)
# AD example:
# (&(objectClass=user)(memberof=CN=MYGROUP,CN=Users,dc=example,dc=com))
# OpenLDAP example: CN=Users,dc=example,dc=com
LDAP_BASE_DN = '<Base-DN>'
 # Configure the bind format string
# Default: LDAP_BIND_FORMAT="
#   {LDAP_USERNAME_ATTRIBUTE}={LDAP_USERNAME},{LDAP_BASE_DN}"
# The current available options are:
# LDAP_USERNAME_ATTRIBUTE, LDAP_USERNAME, LDAP_BASE_DN
# Example: LDAP_BIND_FORMAT="myldapu...@sales.example.com"
#          LDAP_BIND_FORMAT="NET\\myldapuser"
LDAP_BIND_FORMAT = '{LDAP_USERNAME_ATTRIBUTE}={LDAP_USERNAME},{LDAP_BASE_DN}'
 ##########################################################################
 # Search ldap for further authentication (REQUIRED)
# It can be optional while bind as pgAdmin user
LDAP_SEARCH_BASE_DN = '<Search-Base-DN>'
 # The LDAP attribute indicates whether the DN (Distinguished Names)
# are case sensitive or not
LDAP_DN_CASE_SENSITIVE = False
 # Filter string for the user search.
# For OpenLDAP, '(cn=*)' may well be enough.
# For AD, you might use '(objectClass=user)' (REQUIRED)
LDAP_SEARCH_FILTER = '(objectclass=*)'
 # Search scope for users (one of BASE, LEVEL or SUBTREE)
LDAP_SEARCH_SCOPE = 'SUBTREE'
 # Use TLS? If the URI scheme is ldaps://, this is ignored.
LDAP_USE_STARTTLS = False
 # TLS/SSL certificates. Specify if required, otherwise leave empty
LDAP_CA_CERT_FILE = ''
LDAP_CERT_FILE = ''
LDAP_KEY_FILE = ''
 ##########################################################################
# Kerberos Configuration
##########################################################################
 KRB_APP_HOST_NAME = DEFAULT_SERVER
 # If the default_keytab_name is not set in krb5.conf or
# the KRB_KTNAME environment variable is not set then, explicitly set
# the Keytab file
 KRB_KTNAME = '<KRB5_KEYTAB_FILE>'
 # After kerberos authentication, user will be added into the SQLite database
# automatically, if set to True.
# Set it to False, if user should not be added automatically,
# in this case Admin has to add the user manually in the SQLite database.
 KRB_AUTO_CREATE_USER = True
 KERBEROS_CCACHE_DIR = os.path.join(DATA_DIR, 'krbccache')
 #############################################################################
# Create local directory to store azure credential cache
#############################################################################
 AZURE_CREDENTIAL_CACHE_DIR = os.path.join(DATA_DIR, 'azurecredentialcache')
 ##########################################################################
# OAuth2 Configuration
##########################################################################
 # Multiple OAUTH2 providers can be added in the list like [{...},{...}]
# All parameters are required
 OAUTH2_CONFIG = [
    {
        'OAUTH2_NAME': '<Name>',
        'OAUTH2_DISPLAY_NAME': 'SSO',
        'OAUTH2_CLIENT_ID': '<CLIENT_ID>' ,
        'OAUTH2_CLIENT_SECRET': '<CLIENT_SECRET>' ,
        'OAUTH2_TOKEN_URL':'<AUTHSERVER_URI>' + '/v1/token',
        'OAUTH2_AUTHORIZATION_URL': '<AUTHSERVER_URI>' + '/v1/authorize',
        'OAUTH2_API_BASE_URL': '<AUTHSERVER_URI>',
        'OAUTH2_USERINFO_ENDPOINT':'<AUTHSERVER_URI>' + '/v1/userinfo',
        'OAUTH2_SCOPE': 'address email groups offline_access openid phone 
profile',
        'OAUTH2_ICON': 'None',
        'OAUTH2_BUTTON_COLOR': '0000ff'
    }
]
 # After Oauth authentication, user will be added into the SQLite database
# automatically, if set to True.
# Set it to False, if user should not be added automatically,
# in this case Admin has to add the user manually in the SQLite database.
 OAUTH2_AUTO_CREATE_USER = True
 ##########################################################################
# Webserver Configuration
##########################################################################
 WEBSERVER_AUTO_CREATE_USER = True
 # REMOTE_USER variable will be used to check the environment variable
# is set or not first, if not available,
# request header will be checked for the same.
# Possible values: REMOTE_USER, HTTP_X_FORWARDED_USER, X-Forwarded-User
 WEBSERVER_REMOTE_USER = 'REMOTE_USER'
 ##########################################################################
# Two-factor Authentication Configuration
##########################################################################
 # Set it to True, to enable the two-factor authentication
MFA_ENABLED = True
 # Set it to True, to ask the users to register forcefully for the
# two-authentication methods on logged-in.
MFA_FORCE_REGISTRATION = False
 # pgAdmin supports Two-factor authentication by either sending an one-time code
# to an email, or using the TOTP based application like Google Authenticator.
MFA_SUPPORTED_METHODS = ["email", "authenticator"]
 # NOTE: Please set the 'Mail server settings' to use 'email' as two-factor
#       authentication method.
 # Subject for the email verification code
# Default: <APP_NAME> - Verification Code
# e.g.  pgAdmin 4 - Verification Code
MFA_EMAIL_SUBJECT = None
 ##########################################################################
# PSQL tool settings
##########################################################################
# This will enable PSQL tool in pgAdmin when running in server mode.
# PSQL is always enabled in Desktop mode, however in server mode it is
# disabled by default because users can run arbitrary commands on the
# server through it.
ENABLE_PSQL = False
 ##########################################################################
# ENABLE_BINARY_PATH_BROWSING setting is used to enable the browse button
# while selecting binary path for the database server in server mode.
# In Desktop mode it is always enabled and setting is of no use.
##########################################################################
ENABLE_BINARY_PATH_BROWSING = False
 #############################################################################
# AUTO_DISCOVER_SERVERS setting is used to enable the pgAdmin to discover the
# database server automatically on the local machine.
# When it is set to False, pgAdmin will not discover servers installed on
# the local machine.
#############################################################################
AUTO_DISCOVER_SERVERS = True
 ##########################################################################
# Local config settings
##########################################################################
# User configs loaded from config_local, config_distro etc.
user_config_settings = {}
 # Function to Extract settings from config_local, config_distro etc.
def get_variables_from_module(module_name):
    module = globals().get(module_name, None)
    variables = {}
    if module:
        variables = {key: value for key, value in module.__dict__.items()
                    if not (key.startswith('__') or key.startswith('_'))}
    return variables
 # Load distribution-specific config overrides
try:
    import config_distro
    config_distro_settings = get_variables_from_module('config_distro')
    user_config_settings.update(config_distro_settings)
except ImportError:
    pass
 # Load local config overrides
try:
    import config_local
    config_local_settings = get_variables_from_module('config_local')
    user_config_settings.update(config_local_settings)
except ImportError:
    pass
 # Load system config overrides. We do this last, so that the sysadmin can
# override anything they want from a config file that's in a protected system
# directory and away from pgAdmin to avoid invalidating signatures.
system_config_dir = '/etc/pgadmin'
if sys.platform.startswith('win32'):
    system_config_dir = os.environ['CommonProgramFiles'] + '/pgadmin'
elif sys.platform.startswith('darwin'):
    system_config_dir = '/Library/Preferences/pgadmin'
 if os.path.exists(system_config_dir + '/config_system.py'):
    try:
        sys.path.insert(0, system_config_dir)
        import config_system
        config_system_settings = get_variables_from_module('config_system')
        user_config_settings.update(config_system_settings)
    except ImportError:
        pass
 # Update settings for 'LOG_FILE', 'SQLITE_PATH', 'SESSION_DB_PATH',
# 'AZURE_CREDENTIAL_CACHE_DIR', 'KERBEROS_CCACHE_DIR', 'STORAGE_DIR'
# of DATA_DIR is user defined
data_dir_dependent_settings = ['LOG_FILE', 'SQLITE_PATH', 'SESSION_DB_PATH',
                              'AZURE_CREDENTIAL_CACHE_DIR',
                              'KERBEROS_CCACHE_DIR', 'STORAGE_DIR']
 if 'DATA_DIR' in user_config_settings:
    for setting in data_dir_dependent_settings:
        if setting not in user_config_settings:
            data_dir = user_config_settings['DATA_DIR']
            file_dir_name = os.path.basename(locals().get(setting))
            locals().update({setting: os.path.join(data_dir, file_dir_name)})
 # Finally update config user configs
locals().update(user_config_settings)
 # Override DEFAULT_SERVER value from environment variable.
if 'PGADMIN_CONFIG_DEFAULT_SERVER' in os.environ:
    DEFAULT_SERVER = os.environ['PGADMIN_CONFIG_DEFAULT_SERVER']
 # Disable USER_INACTIVITY_TIMEOUT when SERVER_MODE=False
if not SERVER_MODE:
    USER_INACTIVITY_TIMEOUT = 0
    # Enable PSQL in Desktop Mode.
    ENABLE_PSQL = True

Reply via email to