Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions api/control.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,154 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/SelfCapabilities'
/auth/login:
get:
tags:
- OAuth2
operationId: login
summary: Start the server-hosted login flow
description: |
Redirects the browser to the configured identity provider's authorization endpoint
(server.authorization-url) with a one-time state bound to a short-lived cookie. The
identity provider sends the browser back to /auth/callback. Only available when the
OAuth client properties are configured on the server; the client secret never leaves it.
parameters:
- in: query
name: redirect
required: false
description: Path within the UI to return to after login. Must be a relative path.
schema:
type: string
responses:
'302':
description: Redirect to the identity provider.
'400':
description: The hosted login flow is not configured on this server.
/auth/callback:
get:
tags:
- OAuth2
operationId: loginCallback
summary: Complete the server-hosted login flow
description: |
Receives the authorization code from the identity provider, exchanges it for an identity
token using the server-held client secret, verifies that token exactly like the token
exchange endpoint does, and issues a Unity Catalog access token as the UC_TOKEN cookie
before redirecting back into the UI.
parameters:
- in: query
name: code
required: false
schema:
type: string
- in: query
name: state
required: false
schema:
type: string
- in: query
name: error
required: false
schema:
type: string
- in: query
name: error_description
required: false
schema:
type: string
responses:
'302':
description: Login succeeded; the UC_TOKEN cookie is set and the browser is sent back to the UI.
'400':
description: Missing or mismatched state, an error reported by the identity provider, or an unknown user.
/auth/providers:
get:
tags:
- OAuth2
operationId: getAuthProviders
summary: Which sign-in methods this server offers
description: |
Public (no token required). Lets a UI decide at runtime whether sign-in is required at all
and which entry points to show, so one UI build follows the server's configuration instead
of baking the choice in.
responses:
'200':
description: The available sign-in methods.
content:
application/json:
schema:
$ref: '#/components/schemas/AuthProviders'
/auth/admin/login:
post:
tags:
- OAuth2
operationId: adminLogin
summary: Sign in as the built-in administrator with a password
description: |
Exchanges the administrator password configured on the server (server.admin-password) for
a Unity Catalog access token, returned in the body and set as the UC_TOKEN cookie. Serves
the UI's administrator entry point; unavailable unless the password is configured.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required:
- username
- password
properties:
username:
type: string
password:
type: string
format: password
responses:
'200':
description: Signed in; the UC_TOKEN cookie is set.
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthTokenExchangeInfo'
'400':
description: Administrator login is not configured on this server.
'401':
description: Wrong username or password.
/auth/token/login:
post:
tags:
- OAuth2
operationId: tokenLogin
summary: Open a browser session with an access token already held
description: |
Accepts a Unity Catalog access token issued by this server (the one in etc/conf/token.txt,
for instance) and sets it as the UC_TOKEN cookie, so an operator can reach the UI with the
token instead of a password. The token is verified as any request's token is -- signature,
expiry and an enabled user -- and is handed back unchanged, so the session cannot outlive
it. Tokens from an identity provider go to /auth/tokens instead.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required:
- token
properties:
token:
type: string
format: password
responses:
'200':
description: Signed in; the UC_TOKEN cookie is set.
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthTokenExchangeInfo'
'400':
description: No token supplied.
'401':
description: The token is not valid for sign-in.
/auth/tokens:
post:
tags:
Expand Down Expand Up @@ -321,6 +469,18 @@ components:
type: string
lastModified:
type: string
AuthProviders:
type: object
properties:
authorization_enabled:
type: boolean
description: Whether requests must carry a token at all (server.authorization).
hosted_login:
type: boolean
description: Whether the server-hosted OAuth sign-in (/auth/login) is configured.
admin_login:
type: boolean
description: Whether the administrator password sign-in (/auth/admin/login) is configured.
SelfCapabilities:
type: object
properties:
Expand Down
11 changes: 7 additions & 4 deletions bin/start-uc-with-ui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ cd "$UC_HOME"
# --- UI disabled: original single-process behaviour (exec = server is PID) ---
case "${UC_ENABLE_UI:-}" in
1 | true | TRUE | yes | on) ;;
*) exec bin/start-uc-server --port "$UC_PORT" ;;
*) exec bin/start-uc-server --port "$UC_PORT" "$@" ;;
esac

# --- UI enabled: two processes in one container ---
setsid bin/start-uc-server --port "$UC_PORT" &
setsid bin/start-uc-server --port "$UC_PORT" "$@" &
UC_PID=$!

# The server writes its admin token on first start; wait for it (bounded).
# The server writes its admin token on first start. The UI does not use it -- an operator
# signs in with it at /login/token -- but its arrival is the signal that the server is up.
TOKEN_FILE="$UC_HOME/etc/conf/token.txt"
for _ in $(seq 1 90); do
[ -s "$TOKEN_FILE" ] && break
Expand All @@ -46,7 +47,9 @@ done
exit 1
}

UC_TARGET="http://localhost:${UC_PORT}" UC_TOKEN_FILE="$TOKEN_FILE" \
# The UI talks to the Armeria server directly, on UC_PORT+1: UC_PORT itself is the URL
# transcoder, which exists so dotted names survive a path and which the UI never needs.
UC_TARGET="http://localhost:$((UC_PORT + 1))" \
PORT="$UI_PORT" HOST=0.0.0.0 node ui/server.js &
UI_PID=$!
echo "[uc-ui] UI on :${UI_PORT} -> UC :${UC_PORT}"
Expand Down
Loading
Loading