https://prefect.io logo
Title
k

Kyle Hoffman

04/18/2023, 11:50 AM
Hey all! So I need to start off by apologising if this is the wrong channel to post this, but I'm having a rather simple issue that doesn't seem to make sense to me. Am I correct in assuming that there is no way to secure the Prefect Server deployment? Seems like this is a huge limitation for the open source solution?
1
f

flapili

04/18/2023, 12:03 PM
for now there is no api key or token, but you can easily handle it by yourself
like in a reverse proxy ensure there is a basic auth
k

Kyle Hoffman

04/18/2023, 12:28 PM
But if i'm interacting with
prefect-server
via the cli commands, there isn't a way to pass in the required basic auth values. So you wouldn't be able to have routing based authentication (as there is no way to pass in those auth headers)? It would need to be behind a VPN? So that there is no actual auth behind the htts://my-server-name.prefect.com/api ?
f

flapili

04/18/2023, 12:30 PM
for prefect cloud (the SaaS product) there is auth, but for on-premise there isn't
1
k

Kyle Hoffman

04/18/2023, 12:32 PM
@flapili Thanks so much 🙂
f

flapili

04/18/2023, 12:33 PM
if you are on-premise it's pretty easy to add auth on top of prefect server
k

Kyle Hoffman

04/18/2023, 12:35 PM
But for on-prem stuff, that would be auth that allows you access to the servers url, not actually an auth mechanism within prefect itself?
f

flapili

04/18/2023, 12:37 PM
yes, for now auth mechanism is not yet build-in
1
there are various way to handle that
auth on reverse proxy, ssh tunnel, vpn / private network
k

Kyle Hoffman

04/18/2023, 12:38 PM
Yup, 100%!
Thanks again for confirming my suspicions!
f

flapili

04/18/2023, 12:41 PM
else, you could create a thin wrapper and bypass the cli
👀 2
give me few minutes I'll try the idea
@Kyle Hoffman
# coding: utf-8
from secrets import compare_digest

from fastapi import Depends, FastAPI, status, Security, HTTPException
from fastapi.security.api_key import APIKeyQuery, APIKeyCookie, APIKeyHeader
from fastapi.openapi.utils import get_openapi
from prefect.server.api.server import create_orion_api, create_ui_app


def get_token(
    access_token_query: str | None = Security(APIKeyQuery(name="token", auto_error=False)),
    access_token_header: str | None = Security(APIKeyHeader(name="token", auto_error=False)),
    access_token_cookie: str | None = Security(APIKeyCookie(name="token", auto_error=False)),
):
    if access_token_query is not None:
        return access_token_query

    elif access_token_header is not None:
        return access_token_header

    elif access_token_cookie is not None:
        return access_token_cookie

    else:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="token is missing")


def verify_token(token=Depends(get_token)):
    if compare_digest(token, "secret") is False:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="bad token")


custom_app = FastAPI()
api_app = create_orion_api(dependencies=[Depends(verify_token)])
custom_app.mount("/api", api_app)
custom_app.mount("/", create_ui_app(ephemeral=False))


def openapi():
    partial_schema = get_openapi(title="Prefect API customized", version="0.1.0", routes=api_app.routes)
    new_schema = partial_schema.copy()
    new_schema["paths"] = {}
    for path, value in partial_schema["paths"].items():
        new_schema["paths"][f"/api{path}"] = value

    new_schema["info"]["x-logo"] = {"url": "static/prefect-logo-mark-gradient.png"}
    return new_schema


custom_app.openapi = openapi
a basic setup
🙌 1