minio-mobile
Notes
Plan 1
-
Plan: minio-mobile
plan-minio-mobilePlan: minio-mobile
Vision
A mobile-first, multi-tenant asset portal for MinIO. Stakeholders log in via Keycloak and see only their project's assets. Admins see everything. Replaces the unusable stock MinIO Console on mobile devices.
Projects & Repos Touched
Project/Repo Platform Role in this plan forgejo_admin/minio-playground Forgejo Prototype with auth flow, role-based views forgejo_admin/minio-api Forgejo FastAPI service with Keycloak auth + tenant scoping (to be created) forgejo_admin/minio-app Forgejo SvelteKit production app (to be created) forgejo_admin/minio-sdk Forgejo Shared S3 SDK (owned by pal-e-platform, consumed here) Context
Born from pal-e-platform Phase 24-27 (MinIO Mobile Interface). Phase 24 (SDK) and Phase 26 (Playground v1) completed on pal-e-platform. The scope expanded when we realized this needs multi-tenant auth — stakeholders should be able to log in and see only their project's assets. That makes this a product, not a platform utility.
What's already done:
- minio-sdk v0.1.0 — custom Signature V4 signing, 62 tests, published to Forgejo PyPI (pal-e-platform Phase 24)
- minio-playground v1 — 5 HTML pages, mobile-first CSS, mock data, no auth flow (pal-e-platform Phase 26)
Previous Plan
plan-pal-e-platform— Phases 24-27. Phases 25 and 27 superseded by this plan (deferred on platform, replaced here with auth-aware equivalents).Depends On
phase-pal-e-platform-24-minio-sdk— SDK must be published (COMPLETED).Decisions Made
Decision Rationale Separate project from pal-e-platform Multi-tenant auth + stakeholder access = product, not infrastructure utility. Don't bloat the platform plan. Keycloak auth (not open/tailnet-only) Stakeholders need login. Keycloak groups map to MinIO bucket prefixes for tenant scoping. Playground starts from auth flow Auth is core UX, not a bolt-on. Playground must prototype signin → role-based views before SvelteKit (westside pattern). No third-party S3 SDKs Own the stack. Custom Signature V4 signing. Full HTTP control. (Inherited from Phase 24.) Presigned URLs for file transfer API generates presigned URLs, browser talks directly to MinIO for upload/download. No file byte proxying. Phases
See child phase notes:
list_notes(parent_slug="plan-minio-mobile")Key Files
Phase File Repo Change 1 signin.html, app.js, style.css minio-playground Auth flow + role-based views 2 routes/*.py, auth.py minio-api FastAPI + Keycloak middleware 3 src/routes/** minio-app SvelteKit promotion Verification
- [ ] Playground auth flow approved on phone (390px)
- [ ] API serves all SDK operations with Keycloak token validation
- [ ] Stakeholder sees only their prefix, admin sees everything
- [ ] SvelteKit app deployed to k3s with real Keycloak auth
Epilogue
QA nits and discovered scope tracked here.
Related
plan-pal-e-platform— parent plan (Phases 24, 26 completed there)phase-pal-e-platform-24-minio-sdk— SDK (completed, shared dependency)phase-pal-e-platform-26-minio-playground— Playground v1 (completed)project-frontend-playground— playground CSS paradigmconvention-frontend-css— CSS conventions
Board 1
-
minio-mobile
board-minio-mobileminio-mobile
Phase 6
-
Phase 2c: k8s Deployment + CI
phase-minio-mobile-2c-k8s-deployGoal: Dockerize the MinIO API service, set up Woodpecker CI, push to Harbor, and deploy to k3s with Tailscale funnel.
Owner: Dev agent
Repo:
forgejo_admin/minio-api+forgejo_admin/deploymentsDepends on:
phase-minio-mobile-2b-keycloak-auth(auth must be wired before deploy)Scope
- Dockerfile (Python 3.12 slim, uvicorn)
- Woodpecker CI pipeline: lint, test, build image, push to Harbor
- Harbor project setup for minio-api image
- Kustomize overlay in pal-e-deployments (base + prod)
- k8s Deployment, Service, NetworkPolicy
- Tailscale funnel ingress for API access
- Keycloak credentials + MinIO credentials as k8s secrets
- Service onboarding via pal-e-services Terraform (if applicable)
Deliverables
- Filled after completion
Related
phase-minio-mobile-2-api-auth— parent phasephase-minio-mobile-2b-keycloak-auth— prerequisiteservice-onboarding-sop— deployment SOP
-
Phase 2b: Keycloak Auth + Tenant Scoping
phase-minio-mobile-2b-keycloak-authGoal: Add Keycloak OIDC token validation and tenant-scoped access control to the FastAPI service — stakeholders see only their prefix, admins see everything.
Owner: Dev agent
Repo:
forgejo_admin/minio-apiDepends on:
phase-minio-mobile-2a-fastapi-routes(API routes must exist first)Scope
- Keycloak OIDC token validation middleware — every request must have valid Bearer token
- Decode JWT, validate signature against Keycloak's JWKS endpoint
- Extract role and group claims from token
- Tenant scoping: Keycloak group claims map to MinIO bucket prefixes (e.g., group
westside→ prefixassets/westside/) - Admin role bypasses scoping — sees all buckets and prefixes
- Stakeholder role: list/get/upload scoped to their prefix, no delete, no other buckets
- 401 on missing/invalid token, 403 on out-of-scope access
- Tests: mock Keycloak tokens for unit tests, real Keycloak for integration tests
Auth Model
Role Buckets Prefix Operations admin All All Full CRUD stakeholder assets only Scoped to group claim (e.g., westside/)List, Get, Upload — no Delete Deliverables
- PR #5 merged (squash) — 2026-03-22
auth.py— JWKS caching + JWT validation via PyJWT,TokenUserdataclasspermissions.py— tenant scoping: group claim → prefix, admin bypass, stakeholder restrictions- Auth injected on all 15 endpoints via FastAPI
Depends(get_current_user) - 401 on missing/invalid/expired token, 403 on out-of-scope access
AUTH_DISABLED=truefor local dev — existing integration tests unaffected- 63 new tests (15 auth unit, 28 permissions unit, 20 middleware HTTP-level) — all passing
Related
phase-minio-mobile-2-api-auth— parent phasephase-minio-mobile-2a-fastapi-routes— prerequisite (API routes)phase-minio-mobile-2c-k8s-deploy— next subphase (deploy)
-
Phase 2a: FastAPI Service + SDK Routes
phase-minio-mobile-2a-fastapi-routesGoal: Create a FastAPI service that wraps all MinIO SDK operations as JSON REST endpoints — no auth yet, just the routes and SDK integration.
Owner: Dev agent
Repo:
forgejo_admin/minio-api(to be created)Depends on:
phase-pal-e-platform-24-minio-sdk(completed), minio-sdk #3 (XML escaping fix — must merge first)Scope
- FastAPI app with 15 REST endpoints wrapping all MinioClient methods
- JSON request/response — SDK handles XML internally
- Pydantic models for request/response schemas
- MinIO credentials from env vars (
MINIO_ACCESS_KEY,MINIO_SECRET_KEY,MINIO_ENDPOINT) - Presigned URL generation endpoints (GET and PUT)
- OpenAPI docs at
/docs(Swagger UI) and/openapi.json - Integration tests using httpx test client against live MinIO
pyproject.tomlwith minio-sdk as dependency (from Forgejo PyPI)
API Routes
# Bucket operations GET /api/buckets → list buckets POST /api/buckets → create bucket DELETE /api/buckets/{name} → delete bucket HEAD /api/buckets/{name} → check exists # Object operations GET /api/buckets/{bucket}/objects → list objects (query: prefix, delimiter, max_keys) GET /api/buckets/{bucket}/objects/{key:path} → download / get metadata PUT /api/buckets/{bucket}/objects/{key:path} → upload DELETE /api/buckets/{bucket}/objects/{key:path} → delete POST /api/buckets/{bucket}/objects/delete → batch delete # Presigned URLs POST /api/presign/get → generate presigned download URL POST /api/presign/put → generate presigned upload URL # Multipart POST /api/buckets/{bucket}/objects/{key:path}/multipart → initiate POST /api/buckets/{bucket}/objects/{key:path}/multipart/complete → complete DELETE /api/buckets/{bucket}/objects/{key:path}/multipart → abortNo Auth in This Subphase
Auth is Phase 2b. This subphase ships a working API with no authentication — usable on tailnet only. This lets us validate the SDK integration and API design independently from the auth layer.
Deliverables
- PR #2 merged (squash) — 2026-03-22
- 15 REST endpoints: buckets (4), objects (5), presign (2), multipart (3), batch delete (1)
- Pydantic v2 request/response schemas
- Swagger UI at
/docs, OpenAPI spec at/openapi.json - 27 integration tests (buckets 7, objects 10, presign 3, multipart 7) — all passing against live MinIO
- 100 MiB upload size cap with 413 response + chunked reading
- minio-sdk imported from Forgejo PyPI (not vendored)
- Routing shadow fix: multipart router mounted before objects catch-all
Related
phase-minio-mobile-2-api-auth— parent phaseplan-minio-mobile— parent planphase-minio-mobile-2b-keycloak-auth— next subphase (adds auth)
-
Phase 1: Playground Auth Flow + Role-Based Views
phase-minio-mobile-1-playground-authGoal: Update the existing minio-playground with a signin page, demo account links, and role-based views (admin vs stakeholder) — following the westside-playground auth flow pattern.
Owner: Dev agent
Repo:
forgejo_admin/minio-playgroundDepends on: None (playground v1 already merged)
Scope
Auth Flow Pages (westside pattern)
- signin.html — login form (non-functional prototype) with Demo Account links: "Sign in as Admin", "Sign in as Stakeholder (Westside)", "Sign in as Stakeholder (MCD Tracker)"
- HTML comments documenting
@route,@auth,@api,@interactivity,@gaps,@notes(westside convention) - Post-login redirect logic documented: Keycloak OIDC → token claims → role-based routing
Role-Based Views
- Admin view — sees all buckets (assets, postgres-wal, tf-state-backups), full CRUD, user management link
- Stakeholder view — sees only their project prefix (e.g.,
assets/westside/), read + upload, no delete, no other buckets - Navigation adapts per role (admin nav vs stakeholder nav)
- Stakeholder name shown in header ("Westside Basketball" not "assets/westside/")
Updated Pages
- Existing pages (index, browse, preview, upload, detail) updated to show role-appropriate content
- Stakeholder landing = their project's file browser directly (skip bucket list)
- Admin landing = bucket list (existing index.html)
File Structure (unchanged constraint)
- One
style.css, oneapp.js, HTML files per page - No npm, no frameworks, no build step
- Served with
python3 -m http.server 8080
Deliverables
- PR #5 merged (squash) — 2026-03-21
signin.htmlwith demo accounts: Admin, Stakeholder (Westside), Stakeholder (MCD Tracker)- Role state management via URL params + sessionStorage
- Admin view: all buckets, full CRUD. Stakeholder view: scoped prefix, read + upload only
escapeHtml()on all URL-derived innerHTML (XSS fix, passed re-review)isAllowedPath()enforced on all page renderers (access control fix, passed re-review)- HTML comments with
@route,@auth,@interactivityannotations (westside pattern)
Related
plan-minio-mobile— parent planphase-pal-e-platform-26-minio-playground— playground v1 (completed)project-frontend-playground— playground CSS paradigm- westside-playground
signin.html— reference implementation for auth flow pattern
-
Phase 3: SvelteKit Production App
phase-minio-mobile-3-sveltekitGoal: Promote the approved playground (with auth flow) to a production SvelteKit app with real Keycloak auth and MinIO API integration.
Owner: Dev agent
Repo:
forgejo_admin/minio-app(to be created)Depends on:
phase-minio-mobile-1-playground-auth(playground approved on phone),phase-minio-mobile-2-api-auth(API deployed with auth)Scope
- SvelteKit app — playground HTML becomes routes, mock data becomes
+page.server.jsdata loading - Keycloak OIDC via keycloak-js — real login, token management, role-based routing
- Server-side calls to MinIO API with user's token (tenant-scoped responses)
- Presigned URLs for direct upload/download
- Dockerfile + Woodpecker CI + Harbor + k8s deployment + Tailscale funnel
- Register all repos in project page
Supersedes
phase-pal-e-platform-27-minio-sveltekit(deferred on platform) — same concept but now includes Keycloak auth.Deliverables
- Filled after completion
Related
plan-minio-mobile— parent planphase-pal-e-platform-27-minio-sveltekit— superseded platform phase
- SvelteKit app — playground HTML becomes routes, mock data becomes
-
Phase 2: MinIO API with Keycloak Auth
phase-minio-mobile-2-api-authGoal: FastAPI service exposing MinIO SDK operations with Keycloak token validation and tenant-scoped access (stakeholders see only their prefix).
Owner: Dev agent
Repo:
forgejo_admin/minio-api(to be created)Depends on:
phase-pal-e-platform-24-minio-sdk(SDK published),phase-minio-mobile-1-playground-auth(auth flow approved)Scope
- FastAPI service wrapping all SDK operations as JSON REST endpoints
- Keycloak OIDC token validation middleware — every request must have valid Bearer token
- Tenant scoping: Keycloak group claims map to MinIO bucket prefixes (e.g., group
westside→ prefixassets/westside/) - Admin role bypasses scoping — sees all buckets and prefixes
- Presigned URL generation — frontend uploads/downloads directly to MinIO
- OpenAPI docs at
/docs(Swagger UI) and/openapi.json - Dockerfile + Woodpecker CI + Harbor + k8s deployment
Supersedes
phase-pal-e-platform-25-minio-api(deferred on platform) — same API design but now includes Keycloak auth + tenant scoping.Deliverables
- Filled after completion
Related
plan-minio-mobile— parent planphase-pal-e-platform-25-minio-api— superseded platform phasephase-pal-e-platform-24-minio-sdk— SDK dependency
Project Page 1
-
Project: minio-mobile
project-minio-mobileminio-mobile
Vision
A mobile-first, multi-tenant asset portal for MinIO. Stakeholders log in via Keycloak and see only their project's assets. Admins see everything. Replaces the unusable stock MinIO Console on mobile. Built on a custom S3 SDK with zero third-party dependencies — we own the stack from HTTP signing to pixel rendering.
User Stories
Role Key Story Success Metric Admin (Lucas) admin-browse Browse all MinIO buckets from phone, view images, upload files, manage objects All bucket/object CRUD functional at 390px viewport Stakeholder stakeholder-review Log in and see only my project's assets — answer "what have you shared with me?" Tenant-scoped view shows only project prefix, no cross-project leakage Any user mobile-upload Upload photos from phone camera/gallery with progress feedback Presigned URL upload works on mobile Safari/Chrome, progress bar visible Any user asset-discovery Browse folders, preview images inline with pinch-zoom Thumbnail grid, full-size preview, breadcrumb navigation all functional at 390px Consumer Projects
Other projects store assets in MinIO and their stakeholders access them through minio-mobile:
Project MinIO Prefix Asset Types Stakeholders Westside Basketball assets/westside/Coach photos, sponsor logos, branding, game photos Marcus, coaches, sponsors mcd-tracker assets/mcd-tracker/Receipt images (future) Lucas pal-e-docs assets/docs/Documentation images, diagrams Lucas (admin) These projects don't change code to use minio-mobile. Their assets already exist in MinIO. minio-mobile provides a UI layer on top, scoped by Keycloak group claims.
Plan
Active:
plan-minio-mobilePrevious:
plan-pal-e-platformPhases 24-27 (SDK + playground completed on platform; API + SvelteKit deferred and superseded by this plan)Board
board-minio-mobileStatus
- SDK — v0.1.0 published to Forgejo PyPI. Custom Sig V4 signing, 62 tests, XML escaping fixed (PR #4). Owned by pal-e-platform.
- Playground — v2 merged. Signin page, admin/stakeholder role-based views, XSS + access control hardened. 6 HTML pages, 1 CSS, 1 JS.
- API — Phase 2a in progress. FastAPI service wrapping SDK, no auth yet.
- SvelteKit app — Phase 3, not started. Blocked on API + auth.
Milestones
None yet.
Architecture
System Overview
Phone/Browser → minio-app (SvelteKit) → minio-api (FastAPI) → MinIO S3 (port 9000) ↑ ↑ Keycloak login Credentials stay here presigned URLs ←────── generated here ↓ direct upload/download → MinIO S3Key Architectural Decisions
- Custom S3 SDK, no boto3 — own the stack from HTTP signing to pixel rendering. Full control, no hidden failures.
- Presigned URLs for file transfer — API generates URLs, browser talks directly to MinIO. File bytes never proxy through the API.
- Keycloak group claims = tenant scoping — group
westsidemaps to prefixassets/westside/. No per-user MinIO accounts needed. - Playground-first development — vanilla HTML/CSS/JS prototype approved on phone before SvelteKit promotion. The playground IS the design contract.
- Separate project from pal-e-platform — multi-tenant auth + stakeholder access = product, not infrastructure. SDK stays on platform as shared infra.
Detailed architecture diagrams:
arch-domain-minio-mobile,arch-dataflow-minio-mobile,arch-deployment-minio-mobile(to be created when architecture stabilizes).Repos
Repo Platform Role Status minio-sdk Forgejo Pure Python S3 SDK (owned by pal-e-platform, consumed here) active minio-playground Forgejo Mobile-first vanilla HTML/CSS/JS prototype with auth flow active minio-api Forgejo FastAPI REST service with Keycloak auth + tenant scoping active (in development) minio-app Forgejo SvelteKit production app (to be created in Phase 3) planned Inbox
Query:
list_board_items(board_slug="board-minio-mobile", column="backlog")