diff --git a/app/controllers/admin/education/programs_controller.rb b/app/controllers/admin/education/programs_controller.rb
index dd0df83078a31bbd29a09abcead31c72c10e07fa..fadd7e66dfbcf00a116dc202d2852f9352a83ba9 100644
--- a/app/controllers/admin/education/programs_controller.rb
+++ b/app/controllers/admin/education/programs_controller.rb
@@ -90,7 +90,7 @@ class Admin::Education::ProgramsController < Admin::Education::ApplicationContro
       :featured_image, :featured_image_delete, :featured_image_infos, :featured_image_alt,
       :prerequisites, :objectives, :duration, :registration, :pedagogy,
       :evaluation, :accessibility, :pricing, :contacts, :opportunities, :other,
-      :parent_id, school_ids: [], teacher_ids: []
+      :parent_id, school_ids: []
     )
   end
 end
diff --git a/app/controllers/admin/education/teachers_controller.rb b/app/controllers/admin/education/teachers_controller.rb
index bf200fafe2cb2a3a15900bf0038dfd7e9b719b01..a319549df47a0dc819fbba00f7533766d9252837 100644
--- a/app/controllers/admin/education/teachers_controller.rb
+++ b/app/controllers/admin/education/teachers_controller.rb
@@ -1,46 +1,20 @@
 class Admin::Education::TeachersController < Admin::Education::ApplicationController
-  before_action :get_teacher, except: :index
-
   def index
     @teachers = current_university.people.teachers.accessible_by(current_ability).ordered.page(params[:page])
     breadcrumb
   end
 
   def show
+    @teacher = current_university.people.teachers.accessible_by(current_ability).find(params[:id])
     breadcrumb
     @programs = @teacher.education_programs.ordered.page(params[:page])
   end
 
-  def edit
-    breadcrumb
-    add_breadcrumb t('edit')
-  end
-
-  def update
-    if @teacher.update(teacher_params)
-      redirect_to admin_education_teacher_path(@teacher), notice: t('admin.successfully_updated_html', model: @teacher.to_s)
-    else
-      breadcrumb
-      add_breadcrumb t('edit')
-      render :edit, status: :unprocessable_entity
-    end
-  end
-
   protected
 
-  def get_teacher
-    @teacher = current_university.people.teachers.accessible_by(current_ability).find(params[:id])
-  end
-
   def breadcrumb
     super
-    add_breadcrumb  t('education.teachers', count: 2),
-                    admin_education_teachers_path
+    add_breadcrumb t('education.teachers', count: 2), admin_education_teachers_path
     breadcrumb_for @teacher
   end
-
-  def teacher_params
-    params.require(:university_person)
-          .permit(education_program_ids: [])
-  end
 end
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 90003562089828c7f0fba5d87c8ea69845fd43f1..b0e988a3ecd3e1b1028f2698410906ec369377e7 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -46,6 +46,11 @@ class Communication::Website < ApplicationRecord
   end
 
   def git_dependencies_static
-    (pages + posts + categories + menus + people + [home] + [about]).compact
+    [
+      pages, pages.map(&:explicit_active_storage_blobs).flatten,
+      posts, posts.map(&:explicit_active_storage_blobs).flatten,
+      home, home.explicit_active_storage_blobs,
+      categories, menus, people, about
+    ].flatten.uniq.compact
   end
 end
diff --git a/app/models/communication/website/with_abouts.rb b/app/models/communication/website/with_abouts.rb
index 61085336951158b7738029bdaf3ea375f91a3c95..3923523d890f161aec4176f21ff2f452c0010913 100644
--- a/app/models/communication/website/with_abouts.rb
+++ b/app/models/communication/website/with_abouts.rb
@@ -42,7 +42,7 @@ module Communication::Website::WithAbouts
   def people
     @people ||= (
       posts.collect(&:author) +
-      programs.collect(&:teachers).flatten
+      programs.collect(&:people).flatten
       # TODO researchers via articles
     ).uniq.compact
   end
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 6da3a3c804869cd502228bce23efe10872550379..e6849de4be62c70f43fab582735413f529263da5 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -61,16 +61,17 @@ class Education::Program < ApplicationRecord
              class_name: 'Education::Program',
              foreign_key: :parent_id,
              dependent: :destroy
+  has_many   :teachers,
+             class_name: 'Education::Program::Teacher',
+             dependent: :destroy
+  has_many   :people,
+             through: :teachers,
+             dependent: :destroy
   has_and_belongs_to_many :schools,
                           class_name: 'Education::School',
                           join_table: 'education_programs_schools',
                           foreign_key: 'education_program_id',
                           association_foreign_key: 'education_school_id'
-  has_and_belongs_to_many :teachers,
-                          class_name: 'University::Person',
-                          join_table: 'education_programs_teachers',
-                          foreign_key: 'education_program_id',
-                          association_foreign_key: 'education_teacher_id'
   has_many :websites, -> { distinct }, through: :schools
 
   enum level: {
diff --git a/app/models/education/program/teacher.rb b/app/models/education/program/teacher.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2a85d592810b94c587411e09d6f8374f22b27d56
--- /dev/null
+++ b/app/models/education/program/teacher.rb
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: education_program_teachers
+#
+#  id          :uuid             not null, primary key
+#  description :text
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#  person_id   :uuid             not null
+#  program_id  :uuid             not null
+#
+# Indexes
+#
+#  index_education_program_teachers_on_person_id   (person_id)
+#  index_education_program_teachers_on_program_id  (program_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (person_id => university_people.id)
+#  fk_rails_...  (program_id => education_programs.id)
+#
+class Education::Program::Teacher < ApplicationRecord
+  belongs_to :program, class_name: 'Education::Program'
+  belongs_to :person, class_name: 'University::Person'
+
+  validates :person_id, uniqueness: { scope: :program_id }
+
+  scope :ordered, -> { joins(:person).order('university_people.last_name, university_people.first_name') }
+
+  def to_s
+    person.to_s
+  end
+end
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index cd71ec8e7de22959548715c931a7b08abfe129a8..e5da3f416c45e2b8addd235bbdc87ce1e34e10de 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -41,11 +41,14 @@ class University::Person < ApplicationRecord
                           join_table: :research_journal_articles_researchers,
                           foreign_key: :researcher_id
 
-  has_and_belongs_to_many :education_programs,
-                          class_name: 'Education::Program',
-                          join_table: :education_programs_teachers,
-                          foreign_key: :education_teacher_id,
-                          association_foreign_key: :education_program_id
+  has_many                :education_program_teachers,
+                          class_name: 'Education::Program::Teacher',
+                          foreign_key: :person_id,
+                          dependent: :destroy
+
+  has_many                :education_programs,
+                          through: :education_program_teachers,
+                          source: :program
 
   has_many                :communication_website_posts,
                           class_name: 'Communication::Website::Post',
@@ -96,7 +99,7 @@ class University::Person < ApplicationRecord
     ].flatten.uniq)
   end
 
-  def identifiers
+  def identifiers(website: nil)
     [:static, :author, :researcher, :teacher, :administrator]
   end
 
diff --git a/app/views/admin/education/programs/_form.html.erb b/app/views/admin/education/programs/_form.html.erb
index 28c7b68832c60758b2bf395e152f80d5b7399b6f..d04a9ed2e9d5560ba7ef20ea070f7f363b542ba3 100644
--- a/app/views/admin/education/programs/_form.html.erb
+++ b/app/views/admin/education/programs/_form.html.erb
@@ -66,11 +66,6 @@
         <div class="card-body">
           <%= render 'admin/education/programs/forms/input_with_inheritance', f: f, property: :contacts %>
         </div>
-        <div class="card-body">
-          <%= f.association :teachers,
-                            as: :check_boxes,
-                            collection: current_university.people.teachers.ordered %>
-        </div>
       </div>
     </div>
   </div>
diff --git a/app/views/admin/education/programs/show.html.erb b/app/views/admin/education/programs/show.html.erb
index b3f71ddfdfe79be6e5e33363532073ec06f8dba4..02c7052393b180f0c8f26a3362ae7c53176e1641 100644
--- a/app/views/admin/education/programs/show.html.erb
+++ b/app/views/admin/education/programs/show.html.erb
@@ -96,8 +96,12 @@
         <% if @program.teachers.any? %>
           <h3 class="h5 <%= 'mt-4' if i > 0 %>"><%= Education::Program.human_attribute_name('teachers') %></h3>
           <ul class="list-unstyled">
-            <% @program.teachers.ordered.each do |teacher| %>
-              <li><%= link_to_if can?(:read, teacher), teacher, admin_education_teacher_path(teacher) %></li>
+            <% @program.teachers.includes(:person).ordered.each do |teacher| %>
+              <li>
+                <%= link_to_if  can?(:read, teacher.person),
+                                teacher.person,
+                                admin_education_teacher_path(teacher.person) %>
+              </li>
             <% end %>
           </ul>
         <% end %>
diff --git a/app/views/admin/education/teachers/_form.html.erb b/app/views/admin/education/teachers/_form.html.erb
deleted file mode 100644
index 82d37bc4227c744e5b65520c378546c7dcfafaf6..0000000000000000000000000000000000000000
--- a/app/views/admin/education/teachers/_form.html.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-<%= simple_form_for teacher, url: admin_education_teacher_path(teacher) do |f| %>
-  <div class="card flex-fill w-100">
-    <div class="card-header">
-      <h5 class="card-title mb-0"><%= Education::Program.model_name.human(count: 2) %></h5>
-    </div>
-    <div class="card-body">
-      <%= f.association :education_programs,
-                        as: :check_boxes,
-                        legend_tag: false,
-                        collection: collection_tree(current_university.education_programs),
-                        label_method: ->(p) { sanitize p[:label] },
-                        value_method: ->(p) { p[:id] }  %>
-    </div>
-  </div>
-
-  <% content_for :action_bar_right do %>
-    <%= submit f %>
-  <% end %>
-<% end %>
diff --git a/app/views/admin/education/teachers/edit.html.erb b/app/views/admin/education/teachers/edit.html.erb
deleted file mode 100644
index b3f94ca300bb5361d5c000f96b377bd2bd76eb0e..0000000000000000000000000000000000000000
--- a/app/views/admin/education/teachers/edit.html.erb
+++ /dev/null
@@ -1,3 +0,0 @@
-<% content_for :title, @teacher %>
-
-<%= render 'form', teacher: @teacher %>
diff --git a/db/migrate/20220105151548_create_education_program_teachers.rb b/db/migrate/20220105151548_create_education_program_teachers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..78ef3e5fbc9457c69983776c875f23934a76fff2
--- /dev/null
+++ b/db/migrate/20220105151548_create_education_program_teachers.rb
@@ -0,0 +1,11 @@
+class CreateEducationProgramTeachers < ActiveRecord::Migration[6.1]
+  def change
+    create_table :education_program_teachers, id: :uuid do |t|
+      t.text :description
+      t.references :program, null: false, foreign_key: { to_table: :education_programs }, type: :uuid
+      t.references :person, null: false, foreign_key: { to_table: :university_people }, type: :uuid
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20220105151606_remove_education_programs_teachers_join_table.rb b/db/migrate/20220105151606_remove_education_programs_teachers_join_table.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0ceae8ff29027c9327335e04c1342000196a80c1
--- /dev/null
+++ b/db/migrate/20220105151606_remove_education_programs_teachers_join_table.rb
@@ -0,0 +1,5 @@
+class RemoveEducationProgramsTeachersJoinTable < ActiveRecord::Migration[6.1]
+  def change
+    drop_table :education_programs_teachers
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d7d092b7e3272c731b07f294f7c24ec3fc949fdc..39bb00f0890ff7f80f40231a0baddf0e6e7ab267 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.define(version: 2022_01_05_145516) do
+ActiveRecord::Schema.define(version: 2022_01_05_151606) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
@@ -347,6 +347,16 @@ ActiveRecord::Schema.define(version: 2022_01_05_145516) do
     t.index ["priority", "run_at"], name: "delayed_jobs_priority"
   end
 
+  create_table "education_program_teachers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.text "description"
+    t.uuid "program_id", null: false
+    t.uuid "person_id", null: false
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["person_id"], name: "index_education_program_teachers_on_person_id"
+    t.index ["program_id"], name: "index_education_program_teachers_on_program_id"
+  end
+
   create_table "education_programs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.string "name"
@@ -374,13 +384,6 @@ ActiveRecord::Schema.define(version: 2022_01_05_145516) do
     t.index ["education_school_id", "education_program_id"], name: "school_program"
   end
 
-  create_table "education_programs_teachers", id: false, force: :cascade do |t|
-    t.uuid "education_program_id", null: false
-    t.uuid "education_teacher_id", null: false
-    t.index ["education_program_id", "education_teacher_id"], name: "program_teacher"
-    t.index ["education_teacher_id", "education_program_id"], name: "teacher_program"
-  end
-
   create_table "education_schools", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
     t.uuid "university_id", null: false
     t.string "name"
@@ -576,9 +579,10 @@ ActiveRecord::Schema.define(version: 2022_01_05_145516) do
   add_foreign_key "communication_website_posts", "universities"
   add_foreign_key "communication_website_posts", "university_people", column: "author_id"
   add_foreign_key "communication_websites", "universities"
+  add_foreign_key "education_program_teachers", "education_programs", column: "program_id"
+  add_foreign_key "education_program_teachers", "university_people", column: "person_id"
   add_foreign_key "education_programs", "education_programs", column: "parent_id"
   add_foreign_key "education_programs", "universities"
-  add_foreign_key "education_programs_teachers", "university_people", column: "education_teacher_id"
   add_foreign_key "education_schools", "universities"
   add_foreign_key "research_journal_articles", "research_journal_volumes"
   add_foreign_key "research_journal_articles", "research_journals"
diff --git a/test/fixtures/education/program/teachers.yml b/test/fixtures/education/program/teachers.yml
new file mode 100644
index 0000000000000000000000000000000000000000..552fd1552e954a92c99a1e3bfe36ac7eaed45434
--- /dev/null
+++ b/test/fixtures/education/program/teachers.yml
@@ -0,0 +1,32 @@
+# == Schema Information
+#
+# Table name: education_program_teachers
+#
+#  id          :uuid             not null, primary key
+#  description :text
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#  person_id   :uuid             not null
+#  program_id  :uuid             not null
+#
+# Indexes
+#
+#  index_education_program_teachers_on_person_id   (person_id)
+#  index_education_program_teachers_on_program_id  (program_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (person_id => university_people.id)
+#  fk_rails_...  (program_id => education_programs.id)
+#
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  description: MyText
+  program: one
+  person: one
+
+two:
+  description: MyText
+  program: two
+  person: two
diff --git a/test/models/education/program/teacher_test.rb b/test/models/education/program/teacher_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7806b4fcbda0ece1feda5af3d5b0edbfd585e95d
--- /dev/null
+++ b/test/models/education/program/teacher_test.rb
@@ -0,0 +1,28 @@
+# == Schema Information
+#
+# Table name: education_program_teachers
+#
+#  id          :uuid             not null, primary key
+#  description :text
+#  created_at  :datetime         not null
+#  updated_at  :datetime         not null
+#  person_id   :uuid             not null
+#  program_id  :uuid             not null
+#
+# Indexes
+#
+#  index_education_program_teachers_on_person_id   (person_id)
+#  index_education_program_teachers_on_program_id  (program_id)
+#
+# Foreign Keys
+#
+#  fk_rails_...  (person_id => university_people.id)
+#  fk_rails_...  (program_id => education_programs.id)
+#
+require "test_helper"
+
+class Education::Program::TeacherTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end