minio-mobile

minio-mobile forgejo

Notes

Plan 1
  • Plan: minio-mobile plan-minio-mobile

    Plan: 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.

    • 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 paradigm
    • convention-frontend-css — CSS conventions
Board 1
Phase 6
  • Phase 2c: k8s Deployment + CI phase-minio-mobile-2c-k8s-deploy

    Goal: 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/deployments

    Depends 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
    • phase-minio-mobile-2-api-auth — parent phase
    • phase-minio-mobile-2b-keycloak-auth — prerequisite
    • service-onboarding-sop — deployment SOP
  • Phase 2b: Keycloak Auth + Tenant Scoping phase-minio-mobile-2b-keycloak-auth

    Goal: 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-api

    Depends 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 → prefix assets/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, TokenUser dataclass
    • permissions.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=true for local dev — existing integration tests unaffected
    • 63 new tests (15 auth unit, 28 permissions unit, 20 middleware HTTP-level) — all passing
    • phase-minio-mobile-2-api-auth — parent phase
    • phase-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-routes

    Goal: 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.toml with 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           → abort
    

    No 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
    • phase-minio-mobile-2-api-auth — parent phase
    • plan-minio-mobile — parent plan
    • phase-minio-mobile-2b-keycloak-auth — next subphase (adds auth)
  • Phase 1: Playground Auth Flow + Role-Based Views phase-minio-mobile-1-playground-auth

    Goal: 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-playground

    Depends 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, one app.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.html with 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, @interactivity annotations (westside pattern)
    • plan-minio-mobile — parent plan
    • phase-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-sveltekit

    Goal: 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.js data 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
    • plan-minio-mobile — parent plan
    • phase-pal-e-platform-27-minio-sveltekit — superseded platform phase
  • Phase 2: MinIO API with Keycloak Auth phase-minio-mobile-2-api-auth

    Goal: 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 → prefix assets/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
    • plan-minio-mobile — parent plan
    • phase-pal-e-platform-25-minio-api — superseded platform phase
    • phase-pal-e-platform-24-minio-sdk — SDK dependency
Project Page 1
  • Project: minio-mobile project-minio-mobile

    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. 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-mobile

    Previous: plan-pal-e-platform Phases 24-27 (SDK + playground completed on platform; API + SvelteKit deferred and superseded by this plan)

    Board

    board-minio-mobile

    Status

    • 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 S3
    

    Key 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 westside maps to prefix assets/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")