diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index fde14255b2424bf2460f3febfa4c87ae3b3308cc..a470bdedadba99cd58b7522fe8b557ca999cf6c2 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -6,4 +6,10 @@ class ApplicationController < ActionController::Base
   def configure_permitted_parameters
     devise_parameter_sanitizer.permit(:sign_up, keys: [:invitation_token])
   end
+
+  def authorize_shiftcoordinator
+    unless current_user.shiftcoordinator?
+      render plain: 'Forbidden', status: :forbidden
+    end
+  end
 end
diff --git a/app/controllers/assignments_controller.rb b/app/controllers/assignments_controller.rb
index 878c06c19386d46da9c86027b391ace0d6d1521f..6270499f07cfcbb7a2b4da89578e88b959ffb69a 100644
--- a/app/controllers/assignments_controller.rb
+++ b/app/controllers/assignments_controller.rb
@@ -1,6 +1,7 @@
 require 'icalendar/tzinfo'
 
 class AssignmentsController < ApplicationController
+  before_action :authorize_shiftcoordinator, except: [:index, :by_user]
   before_action :set_session, :set_users
 
   def index
diff --git a/app/controllers/candidates_controller.rb b/app/controllers/candidates_controller.rb
index 09079378d13377fd62ee1a5384b8abb09d6c7ac8..94bff982598118290861808d7f42796fe433fb8e 100644
--- a/app/controllers/candidates_controller.rb
+++ b/app/controllers/candidates_controller.rb
@@ -1,6 +1,8 @@
 require 'icalendar/tzinfo'
 
 class CandidatesController < ApplicationController
+  before_action :authorize_shiftcoordinator, except: [:create, :destroy_self]
+
   def create
     @session = Session.find_by(ref_id: params[:session_ref_id])
     @conference = Conference.find_by(slug: params[:conference_slug])
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 6a2eda15af99efbbfddf78c8234fd76ef8f2005d..2dd6bf2df1723d243ba95ee622f7f32684f046eb 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -2,6 +2,7 @@ module ApplicationHelper
   def body_data_attributes
     attributes = {}
     attributes[:loggedin_uid] = current_user.id if user_signed_in?
+    attributes[:is_shiftcoordinator] = 1 if current_user&.shiftcoordinator?
     { data: attributes }
   end
 end
diff --git a/app/javascript/controllers/session_controller.js b/app/javascript/controllers/session_controller.js
index e58fcfda4da894fe59306587c0cef29808a6f3ad..a3a9872c73276cc8d2b999da8e492599108d1f46 100644
--- a/app/javascript/controllers/session_controller.js
+++ b/app/javascript/controllers/session_controller.js
@@ -14,6 +14,7 @@ export default class extends Controller {
   connect() {
     const uid = document.body.dataset.loggedinUid;
     const isCandidate = this.candidatesTarget.querySelector(`a.candidate[data-candidate-uid="${uid}"]`);
+    const isShiftcoordinator = document.body.dataset.isShiftcoordinator;
 
     this.element.querySelectorAll('.only-loggedin').forEach(el => {
       hide(el, !uid);
@@ -27,6 +28,9 @@ export default class extends Controller {
     this.element.querySelectorAll('.only-no-candidate').forEach(el => {
       hide(el, isCandidate);
     });
+    this.element.querySelectorAll('.only-shiftcoordinator').forEach(el => {
+      hide(el, !isShiftcoordinator);
+    });
   }
 
   submitWithPrompt(event) {
diff --git a/app/views/assignments/_user_avatar.html.erb b/app/views/assignments/_user_avatar.html.erb
index 8f1cc9b938307ce8705c82ca4ce420b8939ff7a6..a22856edc9601909d4cf88525706a5894a68b045 100644
--- a/app/views/assignments/_user_avatar.html.erb
+++ b/app/views/assignments/_user_avatar.html.erb
@@ -1,7 +1,7 @@
 <% user = assignment.user %>
 <span class="inline-flex items-center gap-x-0.5 rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
   <span style="color: <%= user.text_color %>"><%= user.name %></span>
-  <button type="button" class="group relative -mr-1 size-3.5 rounded-sm hover:bg-gray-500/20">
+  <button type="button" class="only-shiftcoordinator hidden group relative -mr-1 size-3.5 rounded-sm hover:bg-gray-500/20">
     <%= link_to conference_session_assignment_path(assignment.session.conference, assignment.session, assignment), data: { turbo_method: :delete, confirm: 'Are you sure?' }, method: :delete do %>
       <span class="sr-only">Remove</span>
       <svg viewBox="0 0 14 14" class="size-3.5 stroke-gray-600/50 group-hover:stroke-gray-600/75" style="stroke: <%= user.text_color %>">
diff --git a/app/views/candidates/_user_avatar.html.erb b/app/views/candidates/_user_avatar.html.erb
index 8d2c0c89b2ff318b7ce80cbfc22667ba80075513..382cef8dddc6bb9b8b7c61d6c5b8664218197d5f 100644
--- a/app/views/candidates/_user_avatar.html.erb
+++ b/app/views/candidates/_user_avatar.html.erb
@@ -2,7 +2,7 @@
 <% session = candidate.session %>
 <span class="gap-x-0.5 rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-600 ring-1 ring-inset ring-gray-500/10" style="background-color: <%= user.avatar_color %>" title="<%= user.name %>">
   <span style="color: <%= user.text_color %>"><%= user.name %></span>
-  <button type="button" class="group relative -mr-1 size-3.5 rounded-sm hover:bg-gray-500/20">
+  <button type="button" class="only-shiftcoordinator hidden group relative -mr-1 size-3.5 rounded-sm hover:bg-gray-500/20">
     <%= link_to conference_session_assignments_path(session.conference, session, user_id: user.id), class: "candidate", data: { turbo_method: :post, turbo_frame: dom_id(session), candidate_uid: user.id } do %>
       <span class="sr-only">Add</span>
       <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16" stroke-width="1" class="size-3.5 stroke-gray-600/50 group-hover:stroke-gray-600/75 fill-gray-600/50" style="stroke: <%= user.text_color %>; fill: <%= user.text_color %>">
diff --git a/app/views/sessions/_session.html.erb b/app/views/sessions/_session.html.erb
index c220a4435a8a5a20b2e2be268067283a02dbc905..c4df7dad0fb4947a7aa17b43d6e10a522f8e19d3 100644
--- a/app/views/sessions/_session.html.erb
+++ b/app/views/sessions/_session.html.erb
@@ -83,6 +83,7 @@
     </ul>
     <% end %>
     </div>
+    <div class="only-shiftcoordinator hidden">
     <hr>
     <small>unassigned (<%= unassigned_users.length %>)</small>
     <%= render partial: 'assignments/filteredlist', locals: { session: session, users: [] } %>
diff --git a/db/migrate/20241220201657_add_shiftcoordinator_to_users.rb b/db/migrate/20241220201657_add_shiftcoordinator_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..228d1ebe43931402ccfb129a259dca6cb972e5e6
--- /dev/null
+++ b/db/migrate/20241220201657_add_shiftcoordinator_to_users.rb
@@ -0,0 +1,5 @@
+class AddShiftcoordinatorToUsers < ActiveRecord::Migration[7.1]
+  def change
+    add_column :users, :shiftcoordinator, :boolean, null: false, default: false
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d37ec25374513331a99c1d86d95b59d1acbf3a5a..8a993e726cf15f3a5dc9fdbc8a68dd096be2c1f2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.1].define(version: 2024_12_20_161958) do
+ActiveRecord::Schema[7.1].define(version: 2024_12_20_212328) do
   create_table "assignments", force: :cascade do |t|
     t.integer "user_id", null: false
     t.integer "session_id", null: false
@@ -270,15 +270,15 @@ ActiveRecord::Schema[7.1].define(version: 2024_12_20_161958) do
 
   create_table "users", force: :cascade do |t|
     t.string "name"
-    t.string "email", default: "", null: false
+    t.string "email"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.string "avatar_color"
     t.string "telegram_username"
-    t.string "password_digest"
     t.string "encrypted_password", default: "", null: false
     t.datetime "remember_created_at"
-    t.index ["email"], name: "index_users_on_email", unique: true
+    t.boolean "shiftcoordinator", default: false, null: false
+    t.string "invitation_token"
   end
 
   add_foreign_key "assignments", "sessions"