Skip to main content

Authentication Patterns

Authentication is mandatory for every app in the Yundera App Store. Exceptions must be justified in a rationale.md file. There are three supported patterns.

Pattern 1 — SSO via AppShield (preferred)

The AppShield sidecar handles authentication. The backend is only reachable through the sidecar on the internal pcs network and is never exposed directly.

This is the recommended pattern for most apps. See the full template for the complete compose configuration.

Examples: ConvertX, Spliit, Netdata, Stremio, Terminal, Tribler.

Pattern 2 — AppShield + disable the app's self-auth

Some backends have their own login system. When using AppShield, disable the backend's built-in auth so users aren't prompted twice.

myapp-backend:
environment:
# Disable the backend's own authentication
AUTHENTICATION_ENABLED: "false" # varies by app
# or: AUTH_MODE: "none"
# or: --noauth flag
# or: WEBUI_AUTH: "false"

The specific environment variable depends on the application.

Pattern 3 — App keeps its own auth (no AppShield)

When the app's authentication can't or shouldn't be disabled, expose the app directly with Caddy labels and let it handle login itself.

Document default credentials in tips.before_install:

x-casaos:
tips:
before_install:
en_us: |
## Default Credentials
| Username | Password |
|----------|----------|
| `admin` | `$APP_DEFAULT_PASSWORD` |

Examples: Jellyfin, Immich, n8n, Stirling-PDF.

caution

Never hardcode passwords in the compose file. Always use $APP_DEFAULT_PASSWORD for generated credentials.

Checklist

Before submitting your PR:

  • Auth is enabled and documented
  • AppShield pinned to a specific version (currently ghcr.io/yundera/appshield:2.0.3)
  • Sidecar container_name equals top-level name:
  • Caddy labels live only on the sidecar
  • Backend has no ports: and no Caddy labels
  • No auth-${APP_DOMAIN} label anywhere
  • No hardcoded credentials
  • index: /?hash=$AUTH_HASH set when using AppShield