Skip to content

How to add the first user (Admin) to Redash without using the web interface

Justin Clift edited this page Apr 23, 2024 · 4 revisions

Configuring the first Redash user after installation is normally done through a special setup page the first time the Redash web interface is accessed.

Sometimes that's not a suitable approach, such as when Redash is exposed to the public internet and you may not be able to secure it first (firewall, security groups, etc).

For those situations, you can add the user directly to Redash before starting the web interface.

The SQL

The following SQL does that for Redash 10.1.0, though you need to replace the various __PLACEHOLDER__ strings first:

INSERT INTO public.organizations (updated_at, created_at, id, name, slug, settings)
    VALUES (now(), now(), 1, '__ORGANISATION_NAME__', 'default',
            '{"settings": {"beacon_consent": false}}');

INSERT INTO public.groups (id, org_id, type, name, permissions, created_at)
    VALUES (1, 1, 'builtin', 'admin', '{admin,super_admin}', now());

INSERT INTO public.groups (id, org_id, type, name, permissions, created_at)
    VALUES (2, 1, 'builtin', 'default', '{create_dashboard,create_query,edit_dashboard,edit_query,view_query,view_source,execute_query,list_users,schedule_query,list_dashboards,list_alerts,list_data_sources}',
            '2024-04-21 23:25:13.827925+00');

INSERT INTO public.users (updated_at, created_at, id, org_id, name, email, password_hash, groups,
                          api_key, details)
    VALUES (now(), now(), 1, 1, '__USER_FULL_NAME__', '__EMAIL_ADDRESS__', '__PASSWORD__',
            '{1,2}', '__API_KEY__', format('{"active_at": "%s"}', now())::json);

The placeholders

Replace the placeholders as follows:

  • __ORGANISATION_NAME__ - Name of your company or organisation. ie: 'Newdash'
  • __USER_FULL_NAME__ - The name of the user. ie: 'Fred Nurk'
  • __EMAIL_ADDRESS__ - The email address of the user. ie: 'example@example.com'
  • __PASSWORD__ - The hash of the users password, done using sha512_crypt. Details below.
  • __API_KEY__ - The API key for the user, so they can call Redash from scripts and other tools instead of the web interface. Details below.

Generating a password the same way Redash does it

User passwords in Redash are generated using passlib.apps.custom_app_context.

You can generate one exactly the same way, like this:

$ python3
>>> from passlib.apps import custom_app_context as pwd_context
>>> pwd_context.hash("test1234")
'$6$rounds=656000$eU6sYb5n7K.K6hZ0$tNLgO3gqYkCJnjVvdGiW7TluHeWv/3fB5J29byOmnVU66LRYuEzAoXmh/2LSRDReXdfzSg1t7pFncP03os49r0'

Generating an API key the same way Redash does it

You can generate an API key exactly the same way Redash does it, like this:

$ python3
>>> import random
>>> chars = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"
>>> rand = random.SystemRandom()
>>> "".join(rand.choice(chars) for x in range(40))
'uwgC6V8ipibQbru2Y02R4bnjqjeOLwkcQc1pSECs'

How to load that SQL into Redash

Lets say you've saved the above SQL to a file called setup.sql, and replaced the __PLACEHOLDER__ in it.

You then load the setup.sql into Redash using this command:

$ docker compose exec -u postgres -T postgres psql postgres < setup.sql
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1

Those four INSERT 0 1 lines means the 4 SQL statements worked correctly, and you should be able to log into Redash using the web interface. You'll need to start that first if you haven't done so already.

Example

Lets use this SQL:

INSERT INTO public.organizations (updated_at, created_at, id, name, slug, settings)
    VALUES (now(), now(), 1, 'Newdash', 'default', '{"settings": {"beacon_consent": false}}');

INSERT INTO public.groups (id, org_id, type, name, permissions, created_at)
    VALUES (1, 1, 'builtin', 'admin', '{admin,super_admin}', now());

INSERT INTO public.groups (id, org_id, type, name, permissions, created_at)
    VALUES (2, 1, 'builtin', 'default', '{create_dashboard,create_query,edit_dashboard,edit_query,view_query,view_source,execute_query,list_users,schedule_query,list_dashboards,list_alerts,list_data_sources}', '2024-04-21 23:25:13.827925+00');

INSERT INTO public.users (updated_at, created_at, id, org_id, name, email, password_hash, groups, api_key, details)
    VALUES (now(), now(), 1, 1, 'Fred Nurk', 'example@example.com',
            '$6$rounds=656000$eU6sYb5n7K.K6hZ0$tNLgO3gqYkCJnjVvdGiW7TluHeWv/3fB5J29byOmnVU66LRYuEzAoXmh/2LSRDReXdfzSg1t7pFncP03os49r0',
            '{1,2}', 'uwgC6V8ipibQbru2Y02R4bnjqjeOLwkcQc1pSECs', format('{"active_at": "%s"}', now())::json);

Loading it into Redash as above works:

$ docker compose exec -u postgres -T postgres psql postgres < setup.sql
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1

Now when visiting the web interface the standard login is displayed, rather than the setup screen:

image

Logging in using the example@example.com email address and test1234 password (from above) works as expected.

Viewing the user profile page shows the information we provided in the SQL:

image

Success!

Clone this wiki locally