<@ULVA73B9P> I want my app to be ran as a specific...
# ask-marvin
c
@Marvin I want my app to be ran as a specific service account. Is there a way to do this?
m
thought for 321.0 seconds
Great question — “service account” can mean a few things, so a quick check first: - Do you want to run your flow pods with a specific Kubernetes serviceAccountName? - Or do you want your flows to run as a specific OS user (a Linux “service account”) on a host? Here’s how to do both in Prefect 3.x: Option A — Run as a specific OS user with the Process worker (no containers) - The Process worker runs flows as the same OS user that started the worker. - To run as a specific service account, start the worker under that account (e.g., via systemd). - Per-deployment user switching isn’t supported; use separate workers (and work pools/queues) for different users. Example systemd unit:
Copy code
[Unit]
Description=Prefect Process Worker
After=network.target

[Service]
User=svc-prefect
Environment="PREFECT_API_URL=https://<your-prefect-api>"
ExecStart=/usr/bin/prefect worker start --pool my-process-pool
Restart=always

[Install]
WantedBy=multi-user.target
Docs: Daemonize workers (systemd) | Workers overview Option B — Run in containers (Docker/Podman) as a specific UID/GID - With the Docker worker (works with Podman if you expose the Docker-compatible socket), you can: - Set the container user via
container_create_kwargs.user
(e.g.,
1001:1001
) - Or bake it into your image with
USER 1001
- Mount host paths with
volumes
so your flows can access local files - Since you use JFrog Artifactory, configure a
DockerRegistryCredentials
block and reference it in your deployment or work pool. Base job template snippet for a Docker work pool:
Copy code
{
  "job_configuration": {
    "image": "<http://artifactory.myco.com/myproj/myimage:tag|artifactory.myco.com/myproj/myimage:tag>",
    "volumes": [
      "/host/data:/app/data:rw,Z"
    ],
    "container_create_kwargs": {
      "user": "1001:1001"
    },
    "image_pull_policy": "IfNotPresent"
  }
}
Notes: -
volumes
entries are "host_pathcontainer path[mode]". If you’re on Podman with SELinux, add
:Z
(as shown) to relabel content. - You can also set
USER
in your Dockerfile instead of
container_create_kwargs.user
. Jfrog registry credentials (Python example):
Copy code
from prefect_docker.credentials import DockerRegistryCredentials

creds = DockerRegistryCredentials(
    registry_url="<https://artifactory.myco.com>",
    username="svc-prefect",
    password="***"
)
creds.save("jfrog-service", overwrite=True)
Then reference
creds
in your deployment’s
job_variables
(or set it in the pool base job template). Docs: Docker worker how-to | Customize job variables | Manage work pools Option C — Kubernetes: use a specific ServiceAccount (and/or runAsUser) - Create a Kubernetes work pool and set a base job template that includes: -
serviceAccountName
in
pod.spec
- Pod or container
securityContext
with
runAsUser
,
runAsGroup
,
fsGroup
, etc. - You can keep using your Artifactory image and Kubernetes will pull using your configured imagePullSecrets or registry creds. Example fields to include in the base job template:
Copy code
{
  "job_configuration": {
    "image": "<http://artifactory.myco.com/myproj/myimage:tag|artifactory.myco.com/myproj/myimage:tag>",
    "namespace": "my-namespace",
    "pod": {
      "spec": {
        "serviceAccountName": "my-service-account",
        "securityContext": {
          "runAsUser": 1001,
          "runAsGroup": 1001,
          "fsGroup": 1001,
          "runAsNonRoot": true
        }
      }
    }
  }
}
Docs: Kubernetes worker how-to | Prefect Kubernetes integration Given your environment:
- You currently use a Process worker and need local file path access. The simplest path is to run the Process worker as the desired OS service account (Option A). - If you switch to containers with Podman, mount the required host paths and set the container user (Option B). This gives you better isolation while keeping local file access via volumes. - If you’re on K8s, set
serviceAccountName
and securityContext in the pool’s base job template (Option C). Can you confirm which of these you’re targeting (OS user on a host, Docker/Podman, or Kubernetes)? I can provide a ready-to-use template for your chosen route.
c
@Marvin I mean "run as a specific OS user". I am deploying using an in-house deployment method that doesn't let me kick off the job as a custom service account
m
thought for 308.4 seconds
Thanks for clarifying. In Prefect 3.x, the Process worker cannot switch OS users per run — flows inherit the OS user of the worker process itself. There isn’t a supported “run_as_user” flag for the Process worker. Ways to achieve “run as a specific OS user” given your constraint: Option 1 — Run the Process worker as that service account - Start the worker under the desired Linux service account (e.g., with systemd). - All flows polled by that worker will run as that user. - If your in-house deployment doesn’t permit starting the worker as a custom user, see Options 2/3. Docs: Daemonize workers (systemd) | Workers overview Option 2 — Switch to a container worker (Docker/Podman) and set the container user - The worker can still run as your default user, but it will launch containers that run as your target UID/GID. - Set the user either in your image (
USER 1001
) or via job variables (
container_create_kwargs.user
). - Mount your local file paths as volumes so the flow can access them. Example base job template for a Docker work pool:
Copy code
{
  "job_configuration": {
    "image": "<http://artifactory.myco.com/myproj/myimage:tag|artifactory.myco.com/myproj/myimage:tag>",
    "volumes": [
      "/host/data:/app/data:rw,Z"
    ],
    "container_create_kwargs": {
      "user": "1001:1001"
    },
    "image_pull_policy": "IfNotPresent"
  }
}
Notes: - Podman is supported with the Docker worker if you expose a Docker-compatible socket. With SELinux, add
:Z
on volume mounts. - Rootless Podman/Docker can only mount paths the worker’s OS user can read; if the host files are only readable by the target service account, you’ll need appropriate ACLs or rootful engine. Docs: Docker worker how-to | Customize job variables Option 3 — Run a dedicated worker on a machine you control - Stand up a separate host/VM where you can run the Process worker under the correct service account. - Register it to the same work pool and route only the relevant flows to it via queues/labels. A note on “sudo/su” wrappers - There isn’t a supported hook in the Process worker today to reliably prefix the flow command with
sudo -u ...
per run. Even if you tried, it would still require the worker process user to have password-less sudo to that account, which many environments restrict. Follow-ups to choose the best path: - Are you able to run a Docker/Podman worker in your environment? If yes, do your flows need to read host paths that are only accessible to the target service account? (This affects rootless vs. rootful engine and volume mounting.) - If containers aren’t an option, can you run a small, long-lived worker service on any host under the desired service account (Option 3)? I can share a ready-to-use systemd unit. If you confirm which path you prefer, I’ll provide a concrete config/template tailored to your setup (including JFrog registry credentials and volume mounts).