<@ULVA73B9P> How to enable prefect server api with...
# ask-marvin
s
@Marvin How to enable prefect server api with authentication on Ubuntu
m
âś… thought for 103.8 seconds
On Ubuntu, the built-in way to protect a self-hosted Prefect 3.x server is Basic Auth. Quick setup
Copy code
bash
pip install "prefect>=3"

export PREFECT_SERVER_API_AUTH_STRING="admin:StrongPassword123!"
export PREFECT_API_AUTH_STRING="admin:StrongPassword123!"

prefect server start --host 0.0.0.0 --port 4200
Then configure any client/worker that talks to that server:
Copy code
bash
export PREFECT_API_URL="http://<your-server>:4200/api"
export PREFECT_API_AUTH_STRING="admin:StrongPassword123!"
You can test it with:
Copy code
bash
curl -u admin:StrongPassword123! <http://localhost:4200/api/flows>
Important notes - For self-hosted Prefect Server, use
PREFECT_API_AUTH_STRING
, not
PREFECT_API_KEY
-
PREFECT_API_KEY
is for Prefect Cloud - If both are set, the API key can interfere, so unset it for self-hosted usage Recommended production setup on Ubuntu 1. Put credentials in an env file:
Copy code
bash
sudo mkdir -p /etc/prefect
sudo nano /etc/prefect/server.env
Contents:
Copy code
bash
PREFECT_SERVER_API_AUTH_STRING="admin:StrongPassword123!"
PREFECT_API_AUTH_STRING="admin:StrongPassword123!"
PREFECT_API_URL="<http://your-server:4200/api>"
2. Create a systemd service:
Copy code
bash
sudo nano /etc/systemd/system/prefect-server.service
Copy code
ini
[Unit]
Description=Prefect Server
After=network.target

[Service]
Type=simple
EnvironmentFile=/etc/prefect/server.env
ExecStart=/usr/local/bin/prefect server start --host 0.0.0.0 --port 4200
Restart=on-failure

[Install]
WantedBy=multi-user.target
3. Enable it:
Copy code
bash
sudo systemctl daemon-reload
sudo systemctl enable --now prefect-server
sudo systemctl status prefect-server
Security recommendation Basic auth works, but for a real deployment you should also put Prefect behind HTTPS via NGINX or another reverse proxy, otherwise credentials travel unencrypted over HTTP. If you want, I can give you a full Ubuntu + systemd + NGINX + HTTPS example. Relevant docs: - Prefect docs - Run a self-hosted Prefect server - Settings reference
s
I added env and restarted my server service still I'm able to curl the api without Auth (.venv) root@Prefect:/home/prefect# prefect config view 🚀 you are connected to: http://192.168.29.151:4200 PREFECT_PROFILE='ephemeral' PREFECT_API_URL='http://192.168.29.151:4200/api' (from profile) PREFECT_SERVER_ALLOW_EPHEMERAL_MODE='true' (from profile) PREFECT_SERVER_API_AUTH_STRING='********' (from env) (.venv) root@Prefect:/home/prefect#
@Marvin I added env and restarted my server service still I'm able to curl the api without Auth (.venv) root@Prefect:/home/prefect# prefect config view 🚀 you are connected to: http://192.168.29.151:4200 PREFECT_PROFILE='ephemeral' PREFECT_API_URL='http://192.168.29.151:4200/api' (from profile) PREFECT_SERVER_ALLOW_EPHEMERAL_MODE='true' (from profile) PREFECT_SERVER_API_AUTH_STRING='********' (from env) (.venv) root@Prefect:/home/prefect#
m
âś… thought for 152.8 seconds
Most likely, you're testing an endpoint that is intentionally unauthenticated or the running server process never got the env var at startup. A few important things: 1.
prefect config view
in your shell does not prove the server process is using it
It only shows what your current CLI session sees. 2. Auth is only attached when the API app starts If
PREFECT_SERVER_API_AUTH_STRING
was missing when the service started, restarting the shell or setting env later won't enable it. The service must start with that env present. 3.
/api/health
and
/api/ready
are open by design
Those endpoints do not require auth. Try this exact test against a protected endpoint:
Copy code
bash
curl -i <http://192.168.29.151:4200/api/flows>
If auth is working, that should return
401 Unauthorized
. Then test with auth:
Copy code
bash
curl -i -u admin:StrongPassword123! <http://192.168.29.151:4200/api/flows>
If that succeeds, auth is working correctly. Check whether systemd actually passed the env to the service
Copy code
bash
sudo systemctl show prefect-server --property=Environment
You should see
PREFECT_SERVER_API_AUTH_STRING=...
there. Also inspect the service file:
Copy code
bash
sudo systemctl cat prefect-server
You want something like:
Copy code
ini
[Service]
EnvironmentFile=/etc/prefect/server.env
ExecStart=/home/prefect/.venv/bin/prefect server start --host 0.0.0.0 --port 4200
Then reload and fully restart:
Copy code
bash
sudo systemctl daemon-reload
sudo systemctl restart prefect-server
sudo systemctl status prefect-server
Common gotcha If your env file contains quotes or bad formatting, systemd may not load it as expected. Prefer:
Copy code
bash
PREFECT_SERVER_API_AUTH_STRING=admin:StrongPassword123!
not necessarily:
Copy code
bash
PREFECT_SERVER_API_AUTH_STRING="admin:StrongPassword123!"
Best next check Please run these and paste the output:
Copy code
bash
curl -i <http://192.168.29.151:4200/api/flows>
sudo systemctl show prefect-server --property=Environment
sudo systemctl cat prefect-server
If you want, I can help you debug the exact systemd service line-by-line.
s
@Marvin what is ephemeral profile here
m
âś… thought for 5.3 seconds
ephemeral
is Prefect’s temporary local profile that gets used when you haven’t explicitly selected another profile. In practice, it usually means: - Prefect is running in a local/self-hosted context - settings may be coming from your shell env and temporary local defaults - it is not the same thing as a named persistent profile like
default
,
dev
, or
prod
From your output:
Copy code
bash
PREFECT_PROFILE='ephemeral'
PREFECT_API_URL='<http://192.168.29.151:4200/api>' (from profile)
PREFECT_SERVER_ALLOW_EPHEMERAL_MODE='true' (from profile)
that means Prefect created/used a temporary profile context for local usage. Important: this is not the reason auth is bypassed. The auth behavior depends on the server process settings at startup, especially:
Copy code
bash
PREFECT_SERVER_API_AUTH_STRING
So even if your CLI says profile =
ephemeral
, the real question is whether the systemd service started with that variable set. If you want to see your available profiles:
Copy code
bash
prefect profile ls
To inspect the active one:
Copy code
bash
prefect profile inspect
To create and use a normal persistent profile:
Copy code
bash
prefect profile create selfhosted
prefect profile use selfhosted
prefect config set PREFECT_API_URL="<http://192.168.29.151:4200/api>"
If you want, I can also explain: - ephemeral profile vs default profile - why Prefect created it on your machine - whether you should switch to a named profile for your server setup
s
@Marvin I added api auth now ui also asks for same basic auth style creds
m
âś… thought for 7.6 seconds
Yes — that’s expected. When you set
PREFECT_SERVER_API_AUTH_STRING
, Prefect protects the server endpoints with HTTP Basic Auth, and since the UI talks to that same server/API, the browser will also prompt for those credentials. So behavior like this is normal: - browser opens Prefect UI - browser gets
401
- browser shows a Basic Auth login popup - after entering
username:password
, UI loads Important limitation Prefect Server auth is very simple for self-hosting: - one shared username/password - no separate UI login - no user accounts / RBAC - UI and API use the same credentials So you cannot natively have: - open UI but protected API - separate UI username/password from API credentials - multiple users with different roles If you want more flexible access control, the usual approach is to put Prefect behind a reverse proxy like NGINX, Traefik, or OAuth proxy and handle auth there. Examples: - Basic auth at NGINX - SSO/OIDC via oauth2-proxy - IP allowlisting for internal-only access If you want, I can show you either: 1. keep Prefect’s built-in auth and make the browser login work cleanly, or 2. remove Prefect auth and use NGINX basic auth / HTTPS instead, which is often better for Ubuntu deployments.