diff --git a/app/controllers/admin/account_actions_controller.rb b/app/controllers/admin/account_actions_controller.rb
index ea56fa0ac72295bea1a6c177a95af12cb88c5ad8..5d5a431400ab06a1c3f66f8205ca2bbfe9a25229 100644
--- a/app/controllers/admin/account_actions_controller.rb
+++ b/app/controllers/admin/account_actions_controller.rb
@@ -30,7 +30,7 @@ module Admin
     end
 
     def resource_params
-      params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses)
+      params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses, :create_account_summary)
     end
   end
 end
diff --git a/app/controllers/api/v1/admin/account_actions_controller.rb b/app/controllers/api/v1/admin/account_actions_controller.rb
index 29c9b7107bf1a1cec4c065036d991abb8a177f08..8febf4b3ad55f9b78a7ee9f97db388a5908a1664 100644
--- a/app/controllers/api/v1/admin/account_actions_controller.rb
+++ b/app/controllers/api/v1/admin/account_actions_controller.rb
@@ -26,7 +26,8 @@ class Api::V1::Admin::AccountActionsController < Api::BaseController
       :report_id,
       :warning_preset_id,
       :text,
-      :send_email_notification
+      :send_email_notification,
+      :create_account_summary
     )
   end
 end
diff --git a/app/controllers/settings/deletes_controller.rb b/app/controllers/settings/deletes_controller.rb
index 15a59c999dffe219c06b7e2099ee1fe4fb2875db..26e759a4ab5180009a106a6d783f0c4b6b70165a 100644
--- a/app/controllers/settings/deletes_controller.rb
+++ b/app/controllers/settings/deletes_controller.rb
@@ -46,7 +46,7 @@ class Settings::DeletesController < Settings::BaseController
 
   def destroy_account!
     current_account.suspend!
-    Admin::SuspensionWorker.perform_async(current_user.account_id, true)
+    Admin::SuspensionWorker.perform_async(current_user.account_id, reserve_email: false)
     sign_out
   end
 end
diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js
index b318cadc66c54f79089384a97ad4ad61196b13ad..ae78f488e008b542c8b8a9f2fc2ee166070042a8 100644
--- a/app/javascript/packs/admin.js
+++ b/app/javascript/packs/admin.js
@@ -60,10 +60,23 @@ const onEnableBootstrapTimelineAccountsChange = (target) => {
 
 delegate(document, '#form_admin_settings_enable_bootstrap_timeline_accounts', 'change', ({ target }) => onEnableBootstrapTimelineAccountsChange(target));
 
+const onAccountActionSeverityChange = (target) => {
+  const createAccountSummaryDiv = document.querySelector('.input.with_label.admin_account_action_create_account_summary');
+
+  if (createAccountSummaryDiv) {
+    createAccountSummaryDiv.style.display = (target.value === 'suspend') ? 'block' : 'none';
+  }
+};
+
+delegate(document, '#admin_account_action_type', 'change', ({ target }) => onAccountActionSeverityChange(target));
+
 ready(() => {
   const domainBlockSeverityInput = document.getElementById('domain_block_severity');
   if (domainBlockSeverityInput) onDomainBlockSeverityChange(domainBlockSeverityInput);
 
   const enableBootstrapTimelineAccounts = document.getElementById('form_admin_settings_enable_bootstrap_timeline_accounts');
   if (enableBootstrapTimelineAccounts) onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts);
+
+  const accountActionSeverityInput = document.getElementById('admin_account_action_type');
+  if (accountActionSeverityInput) onAccountActionSeverityChange(accountActionSeverityInput);
 });
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index e9da003a30640e804cefa92e7d51912e77d8a462..fbbc39a8e775063c2d8be4ce620a6ae47ed474a1 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -19,7 +19,10 @@ class Admin::AccountAction
                 :report_id,
                 :warning_preset_id
 
-  attr_reader :warning, :send_email_notification, :include_statuses
+  attr_reader :warning,
+              :send_email_notification,
+              :include_statuses,
+              :create_account_summary
 
   def send_email_notification=(value)
     @send_email_notification = ActiveModel::Type::Boolean.new.cast(value)
@@ -29,6 +32,10 @@ class Admin::AccountAction
     @include_statuses = ActiveModel::Type::Boolean.new.cast(value)
   end
 
+  def create_account_summary=(value)
+    @create_account_summary = ActiveModel::Type::Boolean.new.cast(value)
+  end
+
   def save!
     ApplicationRecord.transaction do
       process_action!
@@ -138,7 +145,7 @@ class Admin::AccountAction
   end
 
   def queue_suspension_worker!
-    Admin::SuspensionWorker.perform_async(target_account.id)
+    Admin::SuspensionWorker.perform_async(target_account.id, summarize_account: create_account_summary)
   end
 
   def process_queue!
diff --git a/app/models/secure_account_summary.rb b/app/models/secure_account_summary.rb
new file mode 100644
index 0000000000000000000000000000000000000000..602afce422a23a78cc2575112ffb8d653cfba5b6
--- /dev/null
+++ b/app/models/secure_account_summary.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+class SecureAccountSummary < ApplicationRecord
+  belongs_to :account
+  attr_encrypted :summary, key: Rails.configuration.x.otp_secret[0...32]
+end
diff --git a/app/services/summarize_account_service.rb b/app/services/summarize_account_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e309b35b80344ceae5823aaf51046bca23ffab77
--- /dev/null
+++ b/app/services/summarize_account_service.rb
@@ -0,0 +1,142 @@
+# frozen_string_literal: true
+
+class SummarizeAccountService < BaseService
+  def call(account)
+    raise ArgumentError, 'Must be a local account' unless account.user&.present?
+
+    @account = account
+    @user    = account.user
+
+    @sessions   = []
+    @following  = []
+    @followers  = []
+    @invited_by = nil
+    @invitees   = []
+    @hashes     = []
+
+    summarize_sessions!
+    summarize_network!
+    summarize_media!
+
+    SecureAccountSummary.create!(
+      account_id: @account.id,
+      summary: Oj.dump(summary_attributes)
+    )
+  end
+
+  private
+
+  def summary_attributes
+    {
+      access: {
+        email: @user.email,
+        sessions: @sessions.uniq,
+      },
+
+      network: {
+        following: @following,
+        followers: @followers,
+        inviter: @invited_by,
+        invitees: @invitees,
+      },
+
+      media: {
+        fingerprints: @hashes.compact.uniq,
+      },
+    }
+  end
+
+  def summarize_sessions!
+    remember_current_session!
+    remember_last_session!
+    remember_other_sessions!
+  end
+
+  def summarize_network!
+    remember_followers!
+    remember_following!
+    remember_invitees!
+    remember_invited_by!
+  end
+
+  def summarize_media!
+    fingerprint_avatar!
+    fingerprint_header!
+    fingerprint_media_attachments!
+  end
+
+  def remember_following!
+    @account.following.find_each do |account|
+      @following << account_uri(account)
+    end
+  end
+
+  def remember_followers!
+    @account.followers.find_each do |account|
+      @followers << account_uri(account)
+    end
+  end
+
+  def remember_invited_by!
+    @invited_by = account_uri(@user.invite.user.account) if @user.invite&.user&.account&.present?
+  end
+
+  def remember_invitees!
+    @user.invites.find_each do |invite|
+      invite.users.find_each do |user|
+        @invitees << account_uri(user.account)
+      end
+    end
+  end
+
+  def remember_current_session!
+    @sessions << ip_and_timestamp(@user.current_sign_in_ip, @user.current_sign_in_at) if @user.current_sign_in_ip&.present?
+  end
+
+  def remember_last_session!
+    @sessions << ip_and_timestamp(@user.last_sign_in_ip, @user.last_sign_in_at) if @user.last_sign_in_ip&.present?
+  end
+
+  def remember_other_sessions!
+    @user.session_activations.find_each do |session_activation|
+      @sessions << ip_and_timestamp(session_activation.ip, session_activation.updated_at)
+    end
+  end
+
+  def fingerprint_avatar!
+    @hashes << fingerprint_attachment(@account.avatar) if @account.avatar.exists?
+  end
+
+  def fingerprint_header!
+    @hashes << fingerprint_attachment(@account.header) if @account.header.exists?
+  end
+
+  def fingerprint_media_attachments!
+    @account.media_attachments.find_each do |media_attachment|
+      @hashes << fingerprint_attachment(media_attachment.file)
+    end
+  end
+
+  CHUNK_SIZE = 16.kilobytes
+
+  def fingerprint_attachment(attachment)
+    adapter = Paperclip.io_adapters.for(attachment)
+    digest  = Digest::SHA256.new
+
+    while (buffer = adapter.read(CHUNK_SIZE))
+      digest.update(buffer)
+    end
+
+    digest.hexdigest
+  rescue Errno::ENOENT, Seahorse::Client::NetworkingError
+    nil
+  end
+
+  def account_uri(account)
+    ActivityPub::TagManager.instance.uri_for(account)
+  end
+
+  def ip_and_timestamp(ip, timestamp)
+    [ip&.to_s, timestamp&.iso8601]
+  end
+end
diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb
index ecc893931d596d9fd00a8a0911ce910be7bf9f95..1f0674e99530f3634a92d7b19bc7ea19eff82e43 100644
--- a/app/services/suspend_account_service.rb
+++ b/app/services/suspend_account_service.rb
@@ -42,6 +42,7 @@ class SuspendAccountService < BaseService
   # @option [Boolean] :reserve_username Keep account record
   # @option [Boolean] :skip_side_effects Side effects are ActivityPub and streaming API payloads
   # @option [Time]    :suspended_at Only applicable when :reserve_username is true
+  # @option [Boolean] :summarize_account Create a secure summary of access, network and media data
   def call(account, **options)
     @account = account
     @options = { reserve_username: true, reserve_email: true }.merge(options)
@@ -52,6 +53,7 @@ class SuspendAccountService < BaseService
       @options[:skip_side_effects] = true
     end
 
+    summarize_account!
     reject_follows!
     purge_user!
     purge_profile!
@@ -60,6 +62,12 @@ class SuspendAccountService < BaseService
 
   private
 
+  def summarize_account!
+    return unless @account.local? && @options[:summarize_account]
+
+    SummarizeAccountService.new.call(@account)
+  end
+
   def reject_follows!
     return if @account.local? || !@account.activitypub?
 
diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml
index 20fbeef335bebb9fb5217aeea2ad4ec5ab3bb2f6..dbfe088488e8a3f79183c960daafac6911ee0bfe 100644
--- a/app/views/admin/account_actions/new.html.haml
+++ b/app/views/admin/account_actions/new.html.haml
@@ -1,6 +1,9 @@
 - content_for :page_title do
   = t('admin.account_actions.title', acct: @account.acct)
 
+- content_for :header_tags do
+  = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
+
 = simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f|
   = f.input :report_id, as: :hidden
 
@@ -10,6 +13,9 @@
   - if @account.local?
     %hr.spacer/
 
+    .fields-group
+      = f.input :create_account_summary, as: :boolean, wrapper: :with_label
+
     .fields-group
       = f.input :send_email_notification, as: :boolean, wrapper: :with_label
 
diff --git a/app/workers/admin/suspension_worker.rb b/app/workers/admin/suspension_worker.rb
index 83c815efd7c1ed624248b0b2213a9688a2aed2aa..72b99ec25eb3e868901fb5f3af8f4f2779009411 100644
--- a/app/workers/admin/suspension_worker.rb
+++ b/app/workers/admin/suspension_worker.rb
@@ -5,7 +5,7 @@ class Admin::SuspensionWorker
 
   sidekiq_options queue: 'pull'
 
-  def perform(account_id, remove_user = false)
-    SuspendAccountService.new.call(Account.find(account_id), reserve_username: true, reserve_email: !remove_user)
+  def perform(account_id, options = {})
+    SuspendAccountService.new.call(Account.find(account_id), **options.symbolize_keys)
   end
 end
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 65951b73bafb5ab30119417aab6c62da9349aca8..65f418dbaf825fcea850d2534a7b6c2dd63a7030 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -9,6 +9,7 @@ en:
       account_warning_preset:
         text: You can use toot syntax, such as URLs, hashtags and mentions
       admin_account_action:
+        create_account_summary: Retain sensitive information such as access IPs, fingerprints of uploaded files, who was following the account and others
         include_statuses: The user will see which toots have caused the moderation action or warning
         send_email_notification: The user will receive an explanation of what happened with their account
         text_html: Optional. You can use toot syntax. You can <a href="%{path}">add warning presets</a> to save time
@@ -73,6 +74,7 @@ en:
       account_warning_preset:
         text: Preset text
       admin_account_action:
+        create_account_summary: Keep evidence
         include_statuses: Include reported toots in the e-mail
         send_email_notification: Notify the user per e-mail
         text: Custom warning
diff --git a/db/migrate/20200112170923_create_secure_account_summaries.rb b/db/migrate/20200112170923_create_secure_account_summaries.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bce10ab709ebdb10097211bb05fc3e70e8bc650a
--- /dev/null
+++ b/db/migrate/20200112170923_create_secure_account_summaries.rb
@@ -0,0 +1,11 @@
+class CreateSecureAccountSummaries < ActiveRecord::Migration[5.2]
+  def change
+    create_table :secure_account_summaries do |t|
+      t.bigint :account_id, index: true
+      t.string :encrypted_summary, default: '', null: false
+      t.string :encrypted_summary_iv, default: '', null: false, index: { unique: true }
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5a6b2530c71761a56c874dccad3392f4818a0cfc..23db27f3f82978aca63b9c9d6a4464fcada5b0c9 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: 2019_12_12_003415) do
+ActiveRecord::Schema.define(version: 2020_01_12_170923) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -196,15 +196,26 @@ ActiveRecord::Schema.define(version: 2019_12_12_003415) do
     t.index ["target_type", "target_id"], name: "index_admin_action_logs_on_target_type_and_target_id"
   end
 
+  create_table "announcements", force: :cascade do |t|
+    t.text "text", default: "", null: false
+    t.boolean "published", default: false, null: false
+    t.boolean "all_day", default: false, null: false
+    t.datetime "scheduled_at"
+    t.datetime "starts_at"
+    t.datetime "ends_at"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+  end
+
   create_table "backups", force: :cascade do |t|
     t.bigint "user_id"
     t.string "dump_file_name"
     t.string "dump_content_type"
-    t.bigint "dump_file_size"
     t.datetime "dump_updated_at"
     t.boolean "processed", default: false, null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.bigint "dump_file_size"
   end
 
   create_table "blocks", force: :cascade do |t|
@@ -614,6 +625,16 @@ ActiveRecord::Schema.define(version: 2019_12_12_003415) do
     t.index ["scheduled_at"], name: "index_scheduled_statuses_on_scheduled_at"
   end
 
+  create_table "secure_account_summaries", force: :cascade do |t|
+    t.bigint "account_id"
+    t.string "encrypted_summary", default: "", null: false
+    t.string "encrypted_summary_iv", default: "", null: false
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["account_id"], name: "index_secure_account_summaries_on_account_id"
+    t.index ["encrypted_summary_iv"], name: "index_secure_account_summaries_on_encrypted_summary_iv", unique: true
+  end
+
   create_table "session_activations", force: :cascade do |t|
     t.string "session_id", null: false
     t.datetime "created_at", null: false
diff --git a/spec/fabricators/secure_account_summary_fabricator.rb b/spec/fabricators/secure_account_summary_fabricator.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6005ff32806a26d85d846a8ad48df4f2ed58c744
--- /dev/null
+++ b/spec/fabricators/secure_account_summary_fabricator.rb
@@ -0,0 +1,4 @@
+Fabricator(:secure_account_summary) do
+  account
+  summary "{}"
+end
diff --git a/spec/models/secure_account_summary_spec.rb b/spec/models/secure_account_summary_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..891c1818943d519c67fd2a6d89d5553c74622b8b
--- /dev/null
+++ b/spec/models/secure_account_summary_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+
+RSpec.describe SecureAccountSummary, type: :model do
+end