[BUG] Immich-cli upload does not support SSO #540

Closed
opened 2026-02-04 21:15:16 +03:00 by OVERLORD · 10 comments
Owner

Originally created by @StarkZarn on GitHub (Dec 31, 2022).

Describe the bug
Immich-CLI does not provide a mechanism to authenticate via SSO when OIDC/OAUTH is configured.

Task List

  • I have read thoroughly the README setup and installation instructions.
  • I have included my docker-compose file.
  • I have included my redacted .env file.
  • I have included information on my machine, and environment.

To Reproduce
Steps to reproduce the behavior:

  1. Using the docker image for immich-cli, run immich upload -s http://servername:3001 -e user@domain.tld -pw 'SSO Password' -d /import
  2. Observe "Error logging in - check email and password"

Expected behavior
Additional command line flags should be provided to authenticate via the configured SSO service so that command line upload can work with users that aren't natively managed by Immich.

System

  • Phone OS [iOS, Android]: Android
  • Server Version: 1.40.0
  • Mobile App Version: 1.40.0 build.63

Docker-compose

networks:
  traefik_net:
    external: true
  immich:
    driver: bridge

volumes:
  immich_upload:
    driver: local
    driver_opts:
      type: nfs4
      o: addr=REDACTED,rw,soft,nolock,noatime
      device: ":REDACTED/immich_data"

  librephotos:
    driver: local
    driver_opts:
      type: nfs4
      o: addr=REDACTED,rw,soft,nolock,noatime
      device: ":REDACTED/librephotos_data"        

services:
  immich-server:
    container_name: immich-server
    image: altran1502/immich-server:release
    entrypoint: ["/bin/sh", "./start-server.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-redis
      - immich-database
    restart: always
    networks:
      - traefik_net
      - immich
    labels:
      traefik.enable: "true"
      traefik.http.services.media-immich-api.loadbalancer.server.port: "3001"
      traefik.http.routers.media-immich-api.rule: "Host(`immich.REDACTED`) && Pathprefix(`/api`)"
      traefik.http.routers.media-immich-api.middlewares: service-immich-api-strip,secure-headers@file
      traefik.http.middlewares.service-immich-api-strip.stripprefix.prefixes: "/api"
      traefik.http.routers.media-immich-api.entrypoints: websecure
      traefik.docker.network: traefik_net

  immich-microservices:
    image: altran1502/immich-server:release
    container_name: immich-microservices
    entrypoint: ["/bin/sh", "./start-microservices.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-redis
      - immich-database
    restart: always
    networks:
      - immich

  immich-machine-learning:
    container_name: immich-machine-learning
    image: altran1502/immich-machine-learning:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    volumes:
      - immich_upload:/usr/src/app/upload
    env_file:
      - .env
    environment:
      - NODE_ENV=production
    depends_on:
      - immich-database
    restart: always
    networks:
      - immich

  immich-web:
    container_name: immich-web
    image: altran1502/immich-web:release
    entrypoint: ["/bin/sh", "./entrypoint.sh"]
    env_file:
      - .env
        #    environment:
      # Rename these values for svelte public interface
      #  - PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL}
    restart: always
    networks:
      - immich
      - traefik_net
    labels:
      traefik.enable: "true"
      traefik.http.services.media-immich.loadbalancer.server.port: "3000"
      traefik.http.routers.media-immich.rule: "Host(`immich.REDACTED`)"
      traefik.http.routers.media-immich.entrypoints: websecure
      traefik.docker.network: traefik_net
      traefik.http.routers.media-immich.middlewares: secure-headers@file

  immich-redis:
    container_name: immich-redis
    image: redis:6.2
    restart: always
    networks:
      - immich

  immich-database:
    container_name: immich-database
    image: postgres:14
    env_file:
      - .env
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
    volumes:
      - ./immich/pgdata:/var/lib/postgresql/data
    restart: always
    networks:
      - immich

  immich-uploader:
    container_name: immich-uploader
    image: ghcr.io/immich-app/immich-cli:latest
    networks:
      - immich
    restart: unless-stopped
    volumes:
      - librephotos:/import
        #    command: ['/bin/sleep', '9d']
    entrypoint: ['/bin/sleep', '9d']

.ENV

###################################################################################
# Database
###################################################################################

DB_HOSTNAME=immich-database
DB_USERNAME=immich
DB_PASSWORD=REDACTED
DB_DATABASE_NAME=immich

# Optional Database settings:
# DB_PORT=5432

###################################################################################
# Redis
###################################################################################

REDIS_HOSTNAME=immich-redis

# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=

###################################################################################
# Upload File Location
#
# This is the location where uploaded files are stored.
###################################################################################

#UPLOAD_LOCATION=/bindmount/photos

###################################################################################
# Log message level - [simple|verbose]
###################################################################################

LOG_LEVEL=simple

###################################################################################
# JWT SECRET
#
# This JWT_SECRET is used to sign the authentication keys for user login
# You should set it to a long randomly generated value
# You can use this command to generate one: openssl rand -base64 128
###################################################################################

JWT_SECRET=REDACTED

###################################################################################
# Reverse Geocoding
#
# Reverse geocoding is done locally which has a small impact on memory usage
# This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable
# This ranges from 0-3 with 3 being the most precise
# 3 - Cities > 500 population: ~200MB RAM
# 2 - Cities > 1000 population: ~150MB RAM
# 1 - Cities > 5000 population: ~80MB RAM
# 0 - Cities > 15000 population: ~40MB RAM
####################################################################################

DISABLE_REVERSE_GEOCODING=false
REVERSE_GEOCODING_PRECISION=3

####################################################################################
# WEB - Optional
#
# Custom message on the login page, should be written in HTML form.
# For example:
# PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
####################################################################################

PUBLIC_LOGIN_PAGE_MESSAGE="Welcome to the Photo Gallery!"

####################################################################################
# Alternative Service Addresses - Optional
#
# This is an advanced feature for users who may be running their immich services on different hosts.
# It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers.
# Note: immich-microservices is bound to 3002, but no references are made
####################################################################################

# IMMICH_WEB_URL=http://immich-web:3000
# IMMICH_SERVER_URL=http://immich-server:3001
#IMMICH_SERVER_URL=https://immich.REDACTED
# IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003

####################################################################################
# OAuth Setting - Optional
#
# These setting will enable OAuth login for your instance of Immich
# Folow the instructions in the page https://immich.app/docs/usage/oauth to set up your OAuth provider
####################################################################################

# OAUTH_ENABLED=false
# OAUTH_ISSUER_URL=
# OAUTH_CLIENT_ID=
# OAUTH_CLIENT_SECRET=
# OAUTH_BUTTON_TEXT=Login with OAuth
# OAUTH_AUTO_REGISTER=true
# OAUTH_SCOPE="openid profile email"

Server Info
Running in docker compose on Fedora 37 in a VM, x86_64 architecture.

Originally created by @StarkZarn on GitHub (Dec 31, 2022). <!-- Note: Please search to see if an issue already exists for the bug you encountered. --> **Describe the bug** Immich-CLI does not provide a mechanism to authenticate via SSO when OIDC/OAUTH is configured. **Task List** - [x] I have read thoroughly the README setup and installation instructions. - [x] I have included my `docker-compose` file. - [x] I have included my redacted `.env` file. - [x] I have included information on my machine, and environment. **To Reproduce** Steps to reproduce the behavior: 1. Using the docker image for immich-cli, run `immich upload -s http://servername:3001 -e user@domain.tld -pw 'SSO Password' -d /import` 2. Observe "Error logging in - check email and password" **Expected behavior** Additional command line flags should be provided to authenticate via the configured SSO service so that command line upload can work with users that aren't natively managed by Immich. **System** - Phone OS [iOS, Android]: `Android` - Server Version: `1.40.0` - Mobile App Version: `1.40.0 build.63` **Docker-compose** ``` networks: traefik_net: external: true immich: driver: bridge volumes: immich_upload: driver: local driver_opts: type: nfs4 o: addr=REDACTED,rw,soft,nolock,noatime device: ":REDACTED/immich_data" librephotos: driver: local driver_opts: type: nfs4 o: addr=REDACTED,rw,soft,nolock,noatime device: ":REDACTED/librephotos_data" services: immich-server: container_name: immich-server image: altran1502/immich-server:release entrypoint: ["/bin/sh", "./start-server.sh"] volumes: - immich_upload:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - immich-redis - immich-database restart: always networks: - traefik_net - immich labels: traefik.enable: "true" traefik.http.services.media-immich-api.loadbalancer.server.port: "3001" traefik.http.routers.media-immich-api.rule: "Host(`immich.REDACTED`) && Pathprefix(`/api`)" traefik.http.routers.media-immich-api.middlewares: service-immich-api-strip,secure-headers@file traefik.http.middlewares.service-immich-api-strip.stripprefix.prefixes: "/api" traefik.http.routers.media-immich-api.entrypoints: websecure traefik.docker.network: traefik_net immich-microservices: image: altran1502/immich-server:release container_name: immich-microservices entrypoint: ["/bin/sh", "./start-microservices.sh"] volumes: - immich_upload:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - immich-redis - immich-database restart: always networks: - immich immich-machine-learning: container_name: immich-machine-learning image: altran1502/immich-machine-learning:release entrypoint: ["/bin/sh", "./entrypoint.sh"] volumes: - immich_upload:/usr/src/app/upload env_file: - .env environment: - NODE_ENV=production depends_on: - immich-database restart: always networks: - immich immich-web: container_name: immich-web image: altran1502/immich-web:release entrypoint: ["/bin/sh", "./entrypoint.sh"] env_file: - .env # environment: # Rename these values for svelte public interface # - PUBLIC_IMMICH_SERVER_URL=${IMMICH_SERVER_URL} restart: always networks: - immich - traefik_net labels: traefik.enable: "true" traefik.http.services.media-immich.loadbalancer.server.port: "3000" traefik.http.routers.media-immich.rule: "Host(`immich.REDACTED`)" traefik.http.routers.media-immich.entrypoints: websecure traefik.docker.network: traefik_net traefik.http.routers.media-immich.middlewares: secure-headers@file immich-redis: container_name: immich-redis image: redis:6.2 restart: always networks: - immich immich-database: container_name: immich-database image: postgres:14 env_file: - .env environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} volumes: - ./immich/pgdata:/var/lib/postgresql/data restart: always networks: - immich immich-uploader: container_name: immich-uploader image: ghcr.io/immich-app/immich-cli:latest networks: - immich restart: unless-stopped volumes: - librephotos:/import # command: ['/bin/sleep', '9d'] entrypoint: ['/bin/sleep', '9d'] ``` **.ENV** ``` ################################################################################### # Database ################################################################################### DB_HOSTNAME=immich-database DB_USERNAME=immich DB_PASSWORD=REDACTED DB_DATABASE_NAME=immich # Optional Database settings: # DB_PORT=5432 ################################################################################### # Redis ################################################################################### REDIS_HOSTNAME=immich-redis # Optional Redis settings: # REDIS_PORT=6379 # REDIS_DBINDEX=0 # REDIS_PASSWORD= # REDIS_SOCKET= ################################################################################### # Upload File Location # # This is the location where uploaded files are stored. ################################################################################### #UPLOAD_LOCATION=/bindmount/photos ################################################################################### # Log message level - [simple|verbose] ################################################################################### LOG_LEVEL=simple ################################################################################### # JWT SECRET # # This JWT_SECRET is used to sign the authentication keys for user login # You should set it to a long randomly generated value # You can use this command to generate one: openssl rand -base64 128 ################################################################################### JWT_SECRET=REDACTED ################################################################################### # Reverse Geocoding # # Reverse geocoding is done locally which has a small impact on memory usage # This memory usage can be altered by changing the REVERSE_GEOCODING_PRECISION variable # This ranges from 0-3 with 3 being the most precise # 3 - Cities > 500 population: ~200MB RAM # 2 - Cities > 1000 population: ~150MB RAM # 1 - Cities > 5000 population: ~80MB RAM # 0 - Cities > 15000 population: ~40MB RAM #################################################################################### DISABLE_REVERSE_GEOCODING=false REVERSE_GEOCODING_PRECISION=3 #################################################################################### # WEB - Optional # # Custom message on the login page, should be written in HTML form. # For example: # PUBLIC_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>" #################################################################################### PUBLIC_LOGIN_PAGE_MESSAGE="Welcome to the Photo Gallery!" #################################################################################### # Alternative Service Addresses - Optional # # This is an advanced feature for users who may be running their immich services on different hosts. # It will not change which address or port that services bind to within their containers, but it will change where other services look for their peers. # Note: immich-microservices is bound to 3002, but no references are made #################################################################################### # IMMICH_WEB_URL=http://immich-web:3000 # IMMICH_SERVER_URL=http://immich-server:3001 #IMMICH_SERVER_URL=https://immich.REDACTED # IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003 #################################################################################### # OAuth Setting - Optional # # These setting will enable OAuth login for your instance of Immich # Folow the instructions in the page https://immich.app/docs/usage/oauth to set up your OAuth provider #################################################################################### # OAUTH_ENABLED=false # OAUTH_ISSUER_URL= # OAUTH_CLIENT_ID= # OAUTH_CLIENT_SECRET= # OAUTH_BUTTON_TEXT=Login with OAuth # OAUTH_AUTO_REGISTER=true # OAUTH_SCOPE="openid profile email" ``` **Server Info** Running in docker compose on Fedora 37 in a VM, x86_64 architecture.
Author
Owner

@jrasm91 commented on GitHub (Dec 31, 2022):

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

@jrasm91 commented on GitHub (Dec 31, 2022): I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.
Author
Owner

@alextran1502 commented on GitHub (Dec 31, 2022):

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

Good idea, I like this! I assume it would be encompassed within the Authenticated decorator?

@alextran1502 commented on GitHub (Dec 31, 2022): > I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password. Good idea, I like this! I assume it would be encompassed within the Authenticated decorator?
Author
Owner

@jrasm91 commented on GitHub (Dec 31, 2022):

The passport guard can do a "one of these strategies" thing. So we could support jwt, cookie, API key, etc., by creating a new strategy and implementing the validate method, which returns a user. Nothing else would have to change after that point though.

@jrasm91 commented on GitHub (Dec 31, 2022): The passport guard can do a "one of these strategies" thing. So we could support jwt, cookie, API key, etc., by creating a new strategy and implementing the `validate` method, which returns a user. Nothing else would have to change after that point though.
Author
Owner

@StarkZarn commented on GitHub (Dec 31, 2022):

I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password.

This is what I had in mind when I was looking through things. Admittedly I am not familiar with the SSO functionality here, but a solution in my mind was reminiscent of an "app password" or something. An API key would certainly work well.

@StarkZarn commented on GitHub (Dec 31, 2022): > I think one way to solve this would be by allowing users to generate API keys and then use them with the cli instead of username/password. This is what I had in mind when I was looking through things. Admittedly I am not familiar with the SSO functionality here, but a solution in my mind was reminiscent of an "app password" or something. An API key would certainly work well.
Author
Owner

@StarkZarn commented on GitHub (Jan 10, 2023):

For anyone else who is running into this hurdle, you can simply login as the administrator, reset the user's password, and use local sign-in to upload the photos. The SSO hook isn't a deal breaker as it turns out. To be clear, this won't affect the SSO user's password, it's simply the local immich account.

@StarkZarn commented on GitHub (Jan 10, 2023): For anyone else who is running into this hurdle, you can simply login as the administrator, reset the user's password, and use local sign-in to upload the photos. The SSO hook isn't a deal breaker as it turns out. To be clear, this won't affect the SSO user's password, it's simply the local immich account.
Author
Owner

@StarkZarn commented on GitHub (Jan 10, 2023):

Honestly devs, I think that is a good enough solution if you have other stuff to prioritize. A one-liner about that in the docs would satisfy me.

@StarkZarn commented on GitHub (Jan 10, 2023): Honestly devs, I think that is a good enough solution if you have other stuff to prioritize. A one-liner about that in the docs would satisfy me.
Author
Owner

@jrasm91 commented on GitHub (Jan 10, 2023):

We implemented API keys in the last release, and the PR for CLI to use API keys just got merged.

#1244 and https://github.com/immich-app/CLI/pull/53

@jrasm91 commented on GitHub (Jan 10, 2023): We implemented API keys in the last release, and the PR for CLI to use API keys just got merged. #1244 and https://github.com/immich-app/CLI/pull/53
Author
Owner

@jrasm91 commented on GitHub (Jan 10, 2023):

I haven't gotten around to it, but the docs need to be updated and then we should be all set.

@jrasm91 commented on GitHub (Jan 10, 2023): I haven't gotten around to it, but the docs need to be updated and then we should be all set.
Author
Owner

@alextran1502 commented on GitHub (Jan 10, 2023):

I haven't gotten around to it, but the docs need to be updated and then we should be all set.

I updated the doc

@alextran1502 commented on GitHub (Jan 10, 2023): > I haven't gotten around to it, but the docs need to be updated and then we should be all set. I updated the doc
Author
Owner

@StarkZarn commented on GitHub (Jan 10, 2023):

Sounds like it's properly handled! Thanks so much!

@StarkZarn commented on GitHub (Jan 10, 2023): Sounds like it's properly handled! Thanks so much!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#540