Frontend for the multi-service Embr × Foundry sample. Pairs with embr-multiservice-api — two repos, two embr quickstart deploys, one shared service token.
Browser ─► frontend (this repo) ─► api (sibling repo) ─► Foundry
(Node + Express) (Python + FastAPI)
│
└─ Embr embedded Valkey
Both frontend and API are public on Embr ingress. The API is gated by X-Service-Token, the same secret value being injected into the frontend.
Because Embr's embr.yaml only describes a single app. There's no services: block, no internal network, no service discovery. Until Embr grows a multi-service primitive, partner services have to:
- Each be a separate repo / project / deployment
- Talk to each other over public ingress
- Each defend their own endpoints with their own auth (today, a shared token; ideally, mTLS or workload identity)
This sample illustrates the gap and the workaround.
Deploy the API first (so you have its URL), then the frontend:
# API
embr quickstart deploy embr-devs/embr-multiservice-api
# capture project + env IDs (call them $API_PROJ / $API_ENV)
TOKEN="$(openssl rand -hex 32)"
embr variables set FOUNDRY_BASE_URL "<...>" -p $API_PROJ -e $API_ENV
embr variables set FOUNDRY_API_KEY "<...>" -p $API_PROJ -e $API_ENV --secret
embr variables set FOUNDRY_MODEL_DEPLOYMENT "<deployment>" -p $API_PROJ -e $API_ENV
embr variables set SERVICE_TOKEN "$TOKEN" -p $API_PROJ -e $API_ENV --secret
embr deployments trigger -c HEAD -p $API_PROJ -e $API_ENV
# note the API URL Embr printed
# Frontend
embr quickstart deploy embr-devs/embr-multiservice-frontend
embr variables set API_URL "<api url from previous step>" -p $FE_PROJ -e $FE_ENV
embr variables set SERVICE_TOKEN "$TOKEN" -p $FE_PROJ -e $FE_ENV --secret
embr deployments trigger -c HEAD -p $FE_PROJ -e $FE_ENVOpen the frontend URL, paste a paragraph, click Summarize. Stats come from the API talking to its own Valkey, proving the request really did hop services.
- Drop
SERVICE_TOKENfrom the frontend → confirm calls fail with 401 from the API. Now anyone on the internet who learns the API URL gets the same 401. This is the only line of defense. - Hit the API URL directly without the token → 401. That's the only thing keeping random callers from burning Foundry tokens.
frontend_round_trip_msvsapi_to_foundry_ms— every multi-service call pays public-ingress latency twice. With internal networking, this would be a single intra-cluster hop.
- A
services:block inembr.yamlfor multi-process deployments public: falseto keep services off the internet- Auto-injected
<service>.<project>.embr.internalDNS for siblings, not reachable from outside - Workload identities so siblings don't have to share a long-lived token