MLflow on Hugging Face Spaces with a pragmatic security pattern:
- Anonymous read-only access for MLflow UI and query APIs.
- Authentication required for write operations (create, update, delete).
- MySQL backend persistence with certificate-based TLS.
This repository demonstrates a practical way to keep experiment visibility open while protecting mutations.
MLflow basic auth is typically all-or-nothing. This setup introduces a policy layer at Nginx so you can:
- Keep dashboards discoverable for broad stakeholders.
- Restrict state-changing actions to authenticated users.
- Preserve compatibility with standard MLflow clients.
Current enforcement is implemented in app/nginx.conf:
- Auth required for:
/ajax-api/2.0/mlflow/(experiments|runs)/(create|delete|update) - Anonymous allowed for all other routes via catch-all proxy.
Current container bootstrap is in app/Dockerfile:
- Generates
.htpasswdfromMLFLOW_TRACKING_PASSWORD. - Runs app/mysql_ca.py to materialize MySQL CA cert and append SSL options to
MLFLOW_MYSQL_CONN. - Starts MLflow on
127.0.0.1:5000behind Nginx on7860.
- Architecture and security model: docs/architecture.md
- Deployment pipeline and enterprise certificate lifecycle: docs/deployment.md
- Configure repository secrets and variables used by .github/workflows/pipeline.yml:
HUGGING_FACE_API_KEYMLFLOW_TRACKING_PASSWORDMLFLOW_TRACKING_USERNAMEMLFLOW_MYSQL_CONNMLFLOW_MYSQL_CAHF_REPO(repository variable)
- Push changes under
app/tomaster. - GitHub Actions runs deploy-app.py, pushes app artifacts to HF Space, and injects Space secrets.
- Access the Space URL:
- Read-only views work anonymously.
- Write operations prompt for auth.
- Now: Nginx policy partition for anonymous reads and authenticated writes.
- Next: Token-based write authorization (header or API token checks at proxy/policy layer).
- Future: OIDC/Auth-proxy model for enterprise identity, RBAC, and audit trails.
- Current route protection covers experiments and runs mutations, not every possible MLflow mutation endpoint.
- Basic auth credentials are single-scope and do not provide role granularity.
- CORS is currently permissive in MLflow startup options.
- Write actions still anonymous:
- Verify regex and auth block in app/nginx.conf.
- MySQL TLS connection errors:
- Check CA secret formatting and generated
ca.pemhandling in app/mysql_ca.py.
- Check CA secret formatting and generated
- Deployment did not update Space:
- Check .github/workflows/pipeline.yml run logs and
HF_REPOvalue.
- Check .github/workflows/pipeline.yml run logs and