Conversation
There was a problem hiding this comment.
Pull request overview
Enables local development against the SPD Auth0 tenant by adding Auth0 auth gating to the frontend, relaxing certain JWT claim requirements, and updating Docker build/runtime behavior to resolve workspace dependency issues.
Changes:
- Updated JWT validation requirements and API user fields to better support service accounts.
- Added Auth0Provider + AuthGate and switched frontend API calls to authenticated requests.
- Reworked API Docker build to build/install workspace wheels and tweaked compose/dev ergonomics.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/stitch-auth/src/stitch/auth/validator.py | Adjusts required JWT claims during validation |
| docker-compose.yml | Tweaks local API container settings (log level, volume mount) |
| deployments/stitch-frontend/src/queries/resources.js | Wires React Query resources to authed API functions |
| deployments/stitch-frontend/src/queries/api.js | Adds authenticated fetch helper and propagates richer errors |
| deployments/stitch-frontend/src/main.jsx | Adds Auth0Provider and wraps app in AuthGate |
| deployments/stitch-frontend/src/hooks/useResources.js | Enables queries only when authenticated; passes token getter |
| deployments/stitch-frontend/src/AuthGate.jsx | Adds login/loading gate for the UI |
| deployments/stitch-frontend/package.json | Adds Auth0 React SDK dependency |
| deployments/api/src/stitch/api/entities.py | Allows nullable name/email in User API model |
| deployments/api/src/stitch/api/db/model/user.py | Makes name/email nullable in DB model |
| deployments/api/src/stitch/api/auth.py | Logs JWT validation failures; stores nullable user fields |
| deployments/api/Dockerfile | Builds wheels for workspace packages and installs into venv |
| Makefile | Adds docker-reboot target to rebuild and restart |
Files not reviewed (1)
- deployments/stitch-frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| createRoot(document.getElementById("root")).render( | ||
| <StrictMode> | ||
| <QueryClientProvider client={queryClient}> | ||
| <App /> | ||
| </QueryClientProvider> | ||
| <Auth0Provider | ||
| domain="rmi-spd.us.auth0.com" | ||
| clientId="TS1V1soQbccAV1sitFFCfUaIlSwHD2S2" | ||
| authorizationParams={{ | ||
| redirect_uri: window.location.origin, | ||
| audience: "https://stitch-api.local", |
There was a problem hiding this comment.
Auth0 tenant configuration is hard-coded in the application entrypoint (domain, clientId, audience). Even though clientId isn’t a secret, hard-coding these values makes it easy to accidentally deploy local/incorrect settings and complicates environment-specific configuration; prefer reading them from import.meta.env (with sensible defaults for local) and failing fast with a clear error if they’re missing.
| createRoot(document.getElementById("root")).render( | |
| <StrictMode> | |
| <QueryClientProvider client={queryClient}> | |
| <App /> | |
| </QueryClientProvider> | |
| <Auth0Provider | |
| domain="rmi-spd.us.auth0.com" | |
| clientId="TS1V1soQbccAV1sitFFCfUaIlSwHD2S2" | |
| authorizationParams={{ | |
| redirect_uri: window.location.origin, | |
| audience: "https://stitch-api.local", | |
| const auth0Domain = | |
| import.meta.env?.VITE_AUTH0_DOMAIN ?? "rmi-spd.us.auth0.com"; | |
| const auth0ClientId = | |
| import.meta.env?.VITE_AUTH0_CLIENT_ID ?? "TS1V1soQbccAV1sitFFCfUaIlSwHD2S2"; | |
| const auth0Audience = | |
| import.meta.env?.VITE_AUTH0_AUDIENCE ?? "https://stitch-api.local"; | |
| if (!auth0Domain || !auth0ClientId || !auth0Audience) { | |
| throw new Error( | |
| "Missing Auth0 configuration: ensure VITE_AUTH0_DOMAIN, VITE_AUTH0_CLIENT_ID, and VITE_AUTH0_AUDIENCE are set.", | |
| ); | |
| } | |
| createRoot(document.getElementById("root")).render( | |
| <StrictMode> | |
| <Auth0Provider | |
| domain={auth0Domain} | |
| clientId={auth0ClientId} | |
| authorizationParams={{ | |
| redirect_uri: window.location.origin, | |
| audience: auth0Audience, |
| RUN --mount=type=cache,target=/root/.cache/uv \ | ||
| uv sync --locked --project deployments/api --no-install-workspace |
There was a problem hiding this comment.
uv sync is executed before the venv at /app/.venv exists, but the final runtime environment is the copied /app/.venv. As written, the locked third-party dependencies installed by uv sync are likely not going into /app/.venv, and pip install /app/dist/*.whl may resolve/install dependencies outside the lockfile (reducing reproducibility). Consider making /app/.venv the environment used by uv sync (or using uv pip sync targeting that venv) so the final image strictly reflects uv.lock.
| RUN python -m venv /app/.venv | ||
| ENV PATH="/app/.venv/bin:$PATH" |
There was a problem hiding this comment.
uv sync is executed before the venv at /app/.venv exists, but the final runtime environment is the copied /app/.venv. As written, the locked third-party dependencies installed by uv sync are likely not going into /app/.venv, and pip install /app/dist/*.whl may resolve/install dependencies outside the lockfile (reducing reproducibility). Consider making /app/.venv the environment used by uv sync (or using uv pip sync targeting that venv) so the final image strictly reflects uv.lock.
| uv build --wheel --out-dir /app/dist deployments/api | ||
|
|
||
| # Install the built wheels into the venv (non-editable, self-contained) | ||
| RUN python -m pip install --no-cache-dir /app/dist/*.whl |
There was a problem hiding this comment.
uv sync is executed before the venv at /app/.venv exists, but the final runtime environment is the copied /app/.venv. As written, the locked third-party dependencies installed by uv sync are likely not going into /app/.venv, and pip install /app/dist/*.whl may resolve/install dependencies outside the lockfile (reducing reproducibility). Consider making /app/.venv the environment used by uv sync (or using uv pip sync targeting that venv) so the final image strictly reflects uv.lock.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
mbarlow12
left a comment
There was a problem hiding this comment.
Nothing majorly jumps out right now other than some structural/architectural concerns. The hooks (useAuth, useResources, useQuery) are scattered around various parts of the codebase. It was mentioned that we're hitting/triggering repeated requests, but I can't say for certain where that might be coming from.
Take this with a big grain of salt, but in a past role, we had dedicated state objects/definitions that helped inform how/when the UI rerendered (and triggered external calls/effects). I don't know if useState is now considered a deprecated pattern, but I wonder if we could get more predictable behavior by more cleanly separating out data & UI.
The only other request is to merge in the latest main changes. Would be helpful to review only the changes in this branch.
| --mount=type=bind,source=uv.lock,target=uv.lock \ | ||
| --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ | ||
| uv sync --locked --package stitch-api | ||
| uv build --wheel --out-dir /app/dist deployments/api |
There was a problem hiding this comment.
When building a python package, the build backed will pickup on the project dependencies specified in the target's pyproject.toml. So when we run uv build --package stitch-api``, it will also build the dependent workspace packages (stitch-core and `stitch-auth`) automatically. The separate builds are redundant. We only need to ensure that the source directories are copied into the container in the correct path.
There was a problem hiding this comment.
If we copy packages/ into the image in a single statement (tests/** is ignored in .dockerignore), it shifts the burden of dependency declaration & management into the target pyproject.toml where there's the requirement to add:
[tool.uv.sources]
stitch-core = { workspace = true }
some-other-package = { workspace = true } # we can also configure custom paths/git repos here tooIt'll add minimal bloat to the image (none right now), but it'll help decouple our infra/docker configuration from out application dependencies.
There was a problem hiding this comment.
but it'll help decouple our infra/docker configuration from out application dependencies.
I think that the actual disconnect here is between the application and the repo definitions. My hesitance to copy in packages is related to the fact that would copy in the whole workspace, but there could be packages there that aren't relevant (i.e. we would have multiple apps) one for API, and if we had seed/etl/whatever touch the DB directly rather than api calls, it would get it's own Dockerfile/deploy, but would probably also live in the workspace, and the dependencies wouldn't always map correctly on the workspace level.
This would be useful if we wanted to keep a shared builder base, but everythin g is small enough that I think we don't need that yet.
The (existing) code smell for me on this is specifying the different context and Dockerfile paths in docker-compose:
services:
api:
build:
context: .
dockerfile: deployments/api/DockerfileI'm much more comfortable when the context for a build is the directory with the Dockerfile in it (and subdirectories, etc.), and anything that isn't in that dir is treated as an (actual) external dep.
There's a bunch of ways to work around this (vendoring, breaking up the repo), but alternately, being explicit with what gets copied into the image is a good safety check and keeps the context smaller.
There was a problem hiding this comment.
I don't see any immediate bugs/concerns, but we should be cognizant of the depth of context provider nesting, especially when they're intertwined at the hook level in useResource.js.
I need to refresh/update my knowledge around React architecture and state management, but as the UI grows in complexity, it's something to keep an eye on.
There was a problem hiding this comment.
100% agree. My goal for this was generally in "Get something where the user can see, or not, contents appropriately". I've not given any actual thought to the frontend architecture, and I'm assuming that we'll optimize in the react session later. Note for @jdhoffa that dragging state around is useful, but also carries GDPR issues. We also need to note that as a flag when evaluating Auth0 (or Azure, or whoever we do OIDC with).
There was a problem hiding this comment.
I'm curious if @jasonbrownrmi has any input or views here
|
Closing, as generally superseded by #10 and #9. A working derivative of this branch has been deployed to Azure in a alternate version of this repo: https://github.com/RMI/stitch-public-v2-deploy-poc/pull/3 That repo will stay open until #10 is resolved. |
Successfully authorize local instance against the spd Auth0 tenant.
username and email to beNone/NULLfor service accounts (probably want to change this)