diff --git a/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml b/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml
deleted file mode 100644
index 5fdb2e46ce00e0ecd5943dd6e1b05f2c13b92c5f..0000000000000000000000000000000000000000
--- a/modules/salesforce_encrypt/config/schema/salesforce_encrypt.schema.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-salesforce.auth_provider_settings.oauth_encrypt:
-  type: mapping
-  label: 'Salesforce OAuth, Encrypted, Provider Settings'
-  mapping:
-    consumer_key:
-      type: string
-      label: 'Consumer Key'
-    consumer_secret:
-      type: string
-      label: 'Consumer Secret'
-    login_url:
-      type: uri
-      label: 'Login URL'
-    encryption_profile:
-      type: encrypt.profile.[%key]
-      label: 'Encryption Profile ID'
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.info.yml b/modules/salesforce_encrypt/salesforce_encrypt.info.yml
index 521059d445a8a40a84db344f4da71a4c2a8cbcac..9842d1a743194e519b14a1e87ba03f5b7ec39995 100644
--- a/modules/salesforce_encrypt/salesforce_encrypt.info.yml
+++ b/modules/salesforce_encrypt/salesforce_encrypt.info.yml
@@ -4,5 +4,6 @@ description: Adds encryption support for auth providers.
 package: Salesforce
 core: 8.x
 dependencies:
+  - key:key
   - encrypt:encrypt
   - salesforce:salesforce
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.install b/modules/salesforce_encrypt/salesforce_encrypt.install
new file mode 100644
index 0000000000000000000000000000000000000000..9f84836ed48954bc00196b295aac1c462e72410b
--- /dev/null
+++ b/modules/salesforce_encrypt/salesforce_encrypt.install
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Requirements and uninstall hooks.
+ */
+
+use Drupal\Core\Url;
+use Drupal\salesforce\EntityNotFoundException;
+
+/**
+ * Throw a runtime error if Salesforce encryption profile is not selected.
+ *
+ * Implements hook_requirements().
+ */
+function salesforce_encrypt_requirements($phase) {
+  $requirements = [];
+  if ($phase == 'runtime') {
+    $profile_id = NULL;
+    try {
+      $profile = \Drupal::service('salesforce.client')->getEncryptionProfile();
+    }
+    catch (EntityNotFoundException $e) {
+      // Noop.
+    }
+    $requirements['salesforce_encrypt'] = [
+      'title' => t('Salesforce Encrypt'),
+      'value' => t('Encryption Profile'),
+    ];
+    if (empty($profile)) {
+      $requirements['salesforce_encrypt'] += [
+        'severity' => REQUIREMENT_ERROR,
+        'description' => t('You need to <a href="@url">select an encryption profile</a> in order to fully enable Salesforce Encrypt and protect sensitive information.', ['@url' => Url::fromRoute('salesforce_encrypt.settings')->toString()]),
+      ];
+    }
+    else {
+      $requirements['salesforce_encrypt'] += [
+        'severity' => REQUIREMENT_OK,
+        'description' => t('Profile id: <a href=":url">%profile</a>', ['%profile' => $profile->id(), ':url' => $profile->url()]),
+      ];
+    }
+  }
+  return $requirements;
+}
+
+/**
+ * Implements hook_uninstall().
+ *
+ * Decrypt and purge our data.
+ */
+function salesforce_encrypt_uninstall() {
+  \Drupal::service('salesforce.client')->disableEncryption();
+  \Drupal::state()->delete('salesforce_encrypt.profile');
+}
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml b/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7825f4241c443285956314e6c9a5f494e33ee884
--- /dev/null
+++ b/modules/salesforce_encrypt/salesforce_encrypt.links.menu.yml
@@ -0,0 +1,6 @@
+salesforce_encrypt.settings:
+  route_name: salesforce_encrypt.settings
+  parent: salesforce.admin_config_salesforce
+  title: Salesforce Encrypt
+  description: 'Encrypt sensitive Salesforce OAuth credentials and identity.'
+  weight: 10
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.module b/modules/salesforce_encrypt/salesforce_encrypt.module
index dd18117fefd1794dcdb72fc0ad4310b2641123d4..96658c1fb3a7da24a9bb6c4e700f167be33d0ffa 100644
--- a/modules/salesforce_encrypt/salesforce_encrypt.module
+++ b/modules/salesforce_encrypt/salesforce_encrypt.module
@@ -6,12 +6,80 @@
  */
 
 use Drupal\encrypt\EncryptionProfileInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Entity\EntityInterface;
 
 /**
  * Implements hook_encryption_profile_predelete().
  *
  * If the assigned Encryption profile gets deleted, reset encryption settings.
  */
-function salesforce_encryption_profile_predelete(EncryptionProfileInterface $entity) {
+function salesforce_encrypt_encryption_profile_predelete(EncryptionProfileInterface $entity) {
   \Drupal::service('salesforce.client')->hookEncryptionProfileDelete($entity);
 }
+
+/**
+ * Implements hook_form_alter().
+ */
+function salesforce_encrypt_form_salesforce_auth_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+  /** @var \Drupal\Core\Config\ImmutableConfig $config */
+  $config = $form_state->getBuildInfo()['auth_config'];
+  if (!$config->hasOverrides('provider_settings')) {
+    return;
+  }
+
+  foreach (Element::children($form['settings']['provider_settings']) as $key) {
+    if ($config->hasOverrides("provider_settings.$key")) {
+      $value = &$form['settings']['provider_settings'][$key];
+      $value['#disabled'] = TRUE;
+      $value['#title'] .= ' <em>' . t('(Overridden)') . '</em>';
+      $value['#description'] .= '<br /><strong>' . t('This value is overridden, you cannot edit it here.') . '</strong>';
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function salesforce_encrypt_entity_type_alter(array &$entity_types) {
+  /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
+  $entity_type = &$entity_types['salesforce_auth'];
+  $entity_type->setLinkTemplate('encryption',
+    "/admin/config/salesforce/authorize/encryption/{salesforce_auth}");
+  $handlers = $entity_type->getHandlerClasses();
+  $handlers['form']['encryption'] = 'Drupal\salesforce_encrypt\Form\SalesforceAuthEncryptForm';
+  $entity_type->setHandlerClass('form', $handlers['form']);
+}
+
+/**
+ * Implements hook_local_tasks_alter().
+ */
+function salesforce_encrypt_local_tasks_alter(&$local_tasks) {
+  // Clone an existing salesforce_auth local task to create our new tab.
+  $local_tasks['entity.salesforce_auth.encryption'] =
+    array_merge($local_tasks['entity.salesforce_auth.revoke'], [
+      'route_name' => 'entity.salesforce_auth.encryption',
+      'title' => t('Encryption'),
+      'base_route' => 'entity.salesforce_auth.edit_form',
+      'provider' => 'salesforce_encrypt',
+      'id' => 'entity.salesforce_auth.encryption',
+    ]);
+
+
+}
+
+/**
+ * Implements hook_entity_operation().
+ */
+function salesforce_encrypt_entity_operation(EntityInterface $entity) {
+  $operations = [];
+  if ($entity->getEntityTypeId() == 'salesforce_auth') {
+    $operations['encryption'] = [
+      'title' => t('Encryption'),
+      'weight' => 200,
+      'url' => $entity->toUrl('encryption'),
+    ];
+  }
+  return $operations;
+}
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.routing.yml b/modules/salesforce_encrypt/salesforce_encrypt.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..695a223e0e7b08417a818f3817b76eff990d6ae5
--- /dev/null
+++ b/modules/salesforce_encrypt/salesforce_encrypt.routing.yml
@@ -0,0 +1,17 @@
+salesforce_encrypt.settings:
+  path: '/admin/config/salesforce/encrypt'
+  defaults:
+    _form: '\Drupal\salesforce_encrypt\Form\SettingsForm'
+    _title: 'Salesforce Encryption'
+    _description: 'Encrypt sensitive Salesforce OAuth credentials and identity.'
+  requirements:
+    _permission: 'administer salesforce encryption'
+
+entity.salesforce_auth.encryption:
+  path: '/admin/config/salesforce/authorize/encryption/{salesforce_auth}'
+  defaults:
+    _entity_form: 'salesforce_auth.encryption'
+  requirements:
+    _permission: 'administer salesforce encryption'
+  options:
+    no_cache: TRUE
diff --git a/modules/salesforce_encrypt/salesforce_encrypt.services.yml b/modules/salesforce_encrypt/salesforce_encrypt.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e39a84aa6714857ea45580e4291312bf03274600
--- /dev/null
+++ b/modules/salesforce_encrypt/salesforce_encrypt.services.yml
@@ -0,0 +1,4 @@
+services:
+  salesforce_encrypt.service:
+    class: Drupal\salesforce_encrypt\SalesforceEncrypt
+    arguments: ['@encrypt.encryption_profile.manager', '@key.config_override', '@config.factory', '@state']
diff --git a/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php b/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php
deleted file mode 100644
index 5c0fbded9fb7bc7af2bcf5bb4c1b12bbe7e3fed5..0000000000000000000000000000000000000000
--- a/modules/salesforce_encrypt/src/Consumer/OAuthEncryptedCredentials.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\salesforce_encrypt\Consumer;
-
-use Drupal\salesforce\Consumer\SalesforceCredentials;
-
-/**
- * OAuth encrypted creds.
- */
-class OAuthEncryptedCredentials extends SalesforceCredentials {
-
-  /**
-   * Encryption profile id.
-   *
-   * @var string
-   */
-  protected $encryptionProfileId;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($consumerKey, $loginUrl, $consumerSecret, $encryptionProfileId) {
-    parent::__construct($consumerKey, $loginUrl, $consumerSecret);
-    $this->encryptionProfileId = $encryptionProfileId;
-  }
-
-  /**
-   * Getter.
-   *
-   * @return string
-   *   The encryption profile id.
-   */
-  public function getEncryptionProfileId() {
-    return $this->encryptionProfileId;
-  }
-
-}
diff --git a/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php b/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..eeae3aec92d937b4528688c82c2d415520d3c77f
--- /dev/null
+++ b/modules/salesforce_encrypt/src/Form/SalesforceAuthEncryptForm.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\salesforce_encrypt\Form;
+
+use Drupal\Core\Entity\EntityConfirmFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\salesforce\Entity\SalesforceAuthConfig;
+use Drupal\salesforce_encrypt\SalesforceEncryptTrait;
+
+class SalesforceAuthEncryptForm extends EntityConfirmFormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return $this->t('Encrypt / decrypt Auth Config %name?', ['%name' => $this->entity->label()]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->t('Encryption is currently %status for Auth Config %name.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelUrl() {
+    return $this->entity->toUrl('collection');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return $this->t('Revoke Auth Token');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    if (!$this->entity instanceof SalesforceAuthConfig) {
+      return;
+    }
+    $this->entity->getPlugin()->revokeAccessToken();
+
+    // Set a message that the entity was deleted.
+    $this->messenger()->addStatus($this->t('Auth token for %label was revoked.', [
+      '%label' => $this->entity->label(),
+    ]));
+
+    $form_state->setRedirectUrl($this->getCancelUrl());
+  }
+
+}
\ No newline at end of file
diff --git a/modules/salesforce_encrypt/src/Form/SettingsForm.php b/modules/salesforce_encrypt/src/Form/SettingsForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d4d223213b1c32f7b05780e8460fd76b55a1882
--- /dev/null
+++ b/modules/salesforce_encrypt/src/Form/SettingsForm.php
@@ -0,0 +1,170 @@
+<?php
+
+namespace Drupal\salesforce_encrypt\Form;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerTrait;
+use Drupal\Core\State\StateInterface;
+use Drupal\encrypt\EncryptionProfileManagerInterface;
+use Drupal\salesforce\EntityNotFoundException;
+use Drupal\salesforce\Storage\SalesforceAuthTokenStorage;
+use Drupal\salesforce_encrypt\SalesforceEncrypt;
+use Drupal\salesforce_encrypt\SalesforceEncryptTrait;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Url;
+
+/**
+ * Base form for key add and edit forms.
+ */
+class SettingsForm extends FormBase {
+
+  use MessengerTrait;
+
+  /**
+   * Profile manager.
+   *
+   * @var \Drupal\encrypt\EncryptionProfileManagerInterface
+   */
+  protected $encryptionProfileManager;
+
+  /**
+   * State service.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * Auth token storage service.
+   *
+   * @var \Drupal\salesforce\Storage\SalesforceAuthTokenStorage
+   */
+  protected $authTokenStorage;
+
+  /**
+   * Auth config storage.
+   *
+   * @var \Drupal\salesforce_encrypt\Storage\SalesforceEncryptedAuthStorage
+   */
+  protected $authConfigStorage;
+
+  /**
+   * Salesforce encrypt service.
+   *
+   * @var \Drupal\salesforce_encrypt\SalesforceEncrypt
+   */
+  protected $salesforceEncrypt;
+
+  /**
+   * SettingsForm constructor.
+   *
+   * @param \Drupal\Core\State\StateInterface $state
+   *   State service.
+   * @param \Drupal\encrypt\EncryptionProfileManagerInterface $encryptionProfileManager
+   *   Encryption profile manager service.
+   */
+  public function __construct(StateInterface $state, EncryptionProfileManagerInterface $encryptionProfileManager, SalesforceAuthTokenStorage $authTokenStorage, EntityTypeManagerInterface $etm, SalesforceEncrypt $salesforceEncrypt) {
+    $this->encryptionProfileManager = $encryptionProfileManager;
+    $this->state = $state;
+    $this->authTokenStorage = $authTokenStorage;
+    $this->authConfigStoage = $etm->getStorage('salesforce_auth');
+    $this->salesforceEncrypt = $salesforceEncrypt;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('state'),
+      $container->get('encrypt.encryption_profile.manager'),
+      $container->get('salesforce.auth_token_storage'),
+      $container->get('entity_type.manager'),
+      $container->get('salesforce_encrypt.service')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'salesforce_encrypt_config';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $options = $this
+      ->encryptionProfileManager
+      ->getEncryptionProfileNamesAsOptions();
+    $default = NULL;
+    try {
+      /** @var \Drupal\encrypt\EncryptionProfileInterface $profile */
+      $profile = $this->salesforceEncrypt->getProfile('salesforce_encrypt.profile');
+      if (!empty($profile)) {
+        $default = $profile->id();
+      }
+    }
+    catch (EntityNotFoundException $e) {
+      $this->messenger()->addError($e->getFormattableMessage());
+      $this->messenger()->addError($this->t('Error while loading encryption profile. You will need to <a href=":encrypt">assign a new encryption profile</a>, then <a href=":oauth">re-authenticate to Salesforce</a>.', [':encrypt' => Url::fromRoute('salesforce_encrypt.settings')->toString(), ':oauth' => Url::fromRoute('salesforce.authorize')->toString()]));
+    }
+
+    $form['profile'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Encryption Profile'),
+      '#description' => $this->t('Choose an encryption profile with which to encrypt Salesforce information.'),
+      '#options' => $options,
+      '#default_value' => $default,
+      '#empty_option' => $this->t('Do not use encryption'),
+    ];
+
+    $form['actions']['#type'] = 'actions';
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->t('Save configuration'),
+      '#button_type' => 'primary',
+    ];
+
+    // By default, render the form using system-config-form.html.twig.
+    $form['#theme'] = 'system_config_form';
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $old_profile_id = $this->state->get('salesforce_encrypt.profile');
+    $profile_id = $form_state->getValue('profile');
+
+    if ($old_profile_id == $profile_id) {
+      // No change to encryption profile. Do nothing.
+      return;
+    }
+
+    $profile = $this
+      ->encryptionProfileManager
+      ->getEncryptionProfile($profile_id);
+    if (empty($profile_id)) {
+      // New profile id empty: disable encryption.
+      $this->client->disableEncryption();
+    }
+    elseif (empty($old_profile_id)) {
+      // Old profile id empty: enable encryption anew.
+      $this->client->enableEncryption($profile);
+    }
+    else {
+      // Changing encryption profiles: disable, then re-enable.
+      $this->client->disableEncryption();
+      $this->client->enableEncryption($profile);
+    }
+    $this->state->resetCache();
+    drupal_set_message($this->t('The configuration options have been saved.'));
+  }
+
+}
diff --git a/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php b/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php
deleted file mode 100644
index 4869e2bfe1f6ee138de1382820830fb8aa2a7f19..0000000000000000000000000000000000000000
--- a/modules/salesforce_encrypt/src/Plugin/SalesforceAuthProvider/SalesforceEncryptedOAuthPlugin.php
+++ /dev/null
@@ -1,293 +0,0 @@
-<?php
-
-namespace Drupal\salesforce_encrypt\Plugin\SalesforceAuthProvider;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Routing\TrustedRedirectResponse;
-use Drupal\Core\Url;
-use Drupal\encrypt\EncryptionProfileInterface;
-use Drupal\encrypt\EncryptionProfileManagerInterface;
-use Drupal\encrypt\EncryptServiceInterface;
-use Drupal\salesforce\EntityNotFoundException;
-use Drupal\salesforce\SalesforceAuthProviderPluginBase;
-use Drupal\salesforce\SalesforceAuthProviderInterface;
-use Drupal\salesforce_encrypt\Consumer\OAuthEncryptedCredentials;
-use Drupal\salesforce_encrypt\SalesforceEncryptedAuthTokenStorageInterface;
-use OAuth\Common\Http\Client\ClientInterface;
-use OAuth\Common\Http\Uri\Uri;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * OAuth provider with encrypted credentials.
- *
- * @Plugin(
- *   id = "oauth_encrypted",
- *   label = @Translation("Salesforce OAuth User-Agent, Encrypted")
- * )
- */
-class SalesforceEncryptedOAuthPlugin extends SalesforceAuthProviderPluginBase {
-
-  /**
-   * OAuth credentials.
-   *
-   * @var \Drupal\salesforce\Consumer\SalesforceCredentials
-   */
-  protected $credentials;
-
-  /**
-   * Encryption profile manager.
-   *
-   * @var \Drupal\encrypt\EncryptionProfileManagerInterface
-   */
-  protected $encryptionProfileManager;
-
-  /**
-   * Encryption service.
-   *
-   * @var \Drupal\encrypt\EncryptServiceInterface
-   */
-  protected $encryption;
-
-  /**
-   * Encryption profile.
-   *
-   * @var \Drupal\encrypt\EncryptionProfileInterface
-   */
-  protected $encryptionProfile;
-
-  /**
-   * Encryption profile id.
-   *
-   * @var string
-   */
-  protected $encryptionProfileId;
-
-  /**
-   * {@inheritdoc}
-   */
-  const SERVICE_TYPE = 'oauth_encrypted';
-
-  /**
-   * {@inheritdoc}
-   */
-  const LABEL = 'OAuth Encrypted';
-
-  /**
-   * Token storage;.
-   *
-   * @var \Drupal\salesforce_encrypt\SalesforceEncryptedAuthTokenStorageInterface
-   */
-  protected $storage;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct($id, OAuthEncryptedCredentials $credentials, ClientInterface $httpClient, SalesforceEncryptedAuthTokenStorageInterface $storage, EncryptionProfileManagerInterface $encryptionProfileManager, EncryptServiceInterface $encrypt) {
-    parent::__construct($credentials, $httpClient, $storage, [], new Uri($credentials->getLoginUrl()));
-    $this->id = $id;
-    $this->encryptionProfileManager = $encryptionProfileManager;
-    $this->encryption = $encrypt;
-    $this->encryptionProfileId = $credentials->getEncryptionProfileId();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    $configuration = array_merge(self::defaultConfiguration(), $configuration);
-    $storage = $container->get('salesforce.auth_token_storage');
-    /** @var \Drupal\encrypt\EncryptServiceInterface $encrypt */
-    $encrypt = $container->get('encryption');
-    $encryptProfileMan = $container->get('encrypt.encryption_profile.manager');
-    if ($configuration['encryption_profile']) {
-      try {
-        $profile = $encryptProfileMan->getEncryptionProfile($configuration['encryption_profile']);
-        $configuration['consumer_key'] = $encrypt->decrypt($configuration['consumer_key'], $profile);
-        $configuration['consumer_secret'] = $encrypt->decrypt($configuration['consumer_secret'], $profile);
-      }
-      catch (\Exception $e) {
-        // Any exception here may cause WSOD, don't allow that to happen.
-        watchdog_exception('SFOAuthEncrypted', $e);
-      }
-    }
-    $cred = new OAuthEncryptedCredentials($configuration['consumer_key'], $configuration['login_url'], $configuration['consumer_secret'], $configuration['encryption_profile']);
-    return new static($configuration['id'], $cred, $container->get('salesforce.http_client_wrapper'), $storage, $encryptProfileMan, $encrypt);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function defaultConfiguration() {
-    $defaults = parent::defaultConfiguration();
-    return array_merge($defaults, [
-      'encryption_profile' => NULL,
-    ]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hookEncryptionProfileDelete(EncryptionProfileInterface $profile) {
-    if ($this->encryptionProfile()->id() == $profile->id()) {
-      // @todo decrypt identity, access token, refresh token, consumer secret, consumer key and re-save
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function encryptionProfile() {
-    if ($this->encryptionProfile) {
-      return $this->encryptionProfile;
-    }
-    elseif (empty($this->encryptionProfileId)) {
-      return NULL;
-    }
-    else {
-      $this->encryptionProfile = $this->encryptionProfileManager
-        ->getEncryptionProfile($this->encryptionProfileId);
-      if (empty($this->encryptionProfile)) {
-        throw new EntityNotFoundException(['id' => $this->encryptionProfileId], 'encryption_profile');
-      }
-      return $this->encryptionProfile;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $options = $this
-      ->encryptionProfileManager
-      ->getEncryptionProfileNamesAsOptions();
-    $default = NULL;
-    try {
-      $profile = $this->encryptionProfile();
-      if (!empty($profile)) {
-        $default = $profile->id();
-      }
-    }
-    catch (EntityNotFoundException $e) {
-      $this->messenger()->addError($e->getFormattableMessage());
-      $this->messenger()->addError($this->t('Error while loading encryption profile. You will need to assign a new encryption profile and re-authenticate to Salesforce.'));
-    }
-
-    if (empty($options)) {
-      $this->messenger()->addError($this->t('Please <a href="@href">create an encryption profile</a> before adding an OAuth Encrypted provider.', ['@href' => Url::fromRoute('entity.encryption_profile.add_form')->toString()]));
-    }
-
-    $form['consumer_key'] = [
-      '#title' => t('Salesforce consumer key'),
-      '#type' => 'textfield',
-      '#description' => t('Consumer key of the Salesforce remote application you want to grant access to. VALUE WILL BE ENCRYPTED ON FORM SUBMISSION.'),
-      '#required' => TRUE,
-      '#default_value' => $this->credentials->getConsumerKey(),
-    ];
-
-    $form['consumer_secret'] = [
-      '#title' => $this->t('Salesforce consumer secret'),
-      '#type' => 'textfield',
-      '#description' => $this->t('Consumer secret of the Salesforce remote application. VALUE WILL BE ENCRYPTED ON FORM SUBMISSION.'),
-      '#required' => TRUE,
-      '#default_value' => $this->credentials->getConsumerSecret(),
-    ];
-
-    $form['login_url'] = [
-      '#title' => t('Login URL'),
-      '#type' => 'textfield',
-      '#default_value' => $this->credentials->getLoginUrl(),
-      '#description' => t('Enter a login URL, either https://login.salesforce.com or https://test.salesforce.com.'),
-      '#required' => TRUE,
-    ];
-    $form['encryption_profile'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Encryption Profile'),
-      '#description' => $this->t('Choose an encryption profile with which to encrypt Salesforce information.'),
-      '#options' => $options,
-      '#default_value' => $default,
-      '#required' => TRUE,
-    ];
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
-    $this->setConfiguration($form_state->getValues());
-    $settings = $form_state->getValue('provider_settings');
-    $this->encryptionProfileId = $settings['encryption_profile'];
-    $consumer_key = $settings['consumer_key'];
-    $settings['consumer_key'] = $this->encrypt($settings['consumer_key']);
-    $settings['consumer_secret'] = $this->encrypt($settings['consumer_secret']);
-    $form_state->setValue('provider_settings', $settings);
-    parent::submitConfigurationForm($form, $form_state);
-
-    // Write the config id to private temp store, so that we can use the same
-    // callback URL for all OAuth applications in Salesforce.
-    /** @var \Drupal\Core\TempStore\PrivateTempStore $tempstore */
-    $tempstore = \Drupal::service('user.private_tempstore')->get('salesforce_oauth');
-    $tempstore->set('config_id', $form_state->getValue('id'));
-
-    try {
-      $path = $this->getAuthorizationEndpoint();
-      $query = [
-        'redirect_uri' => $this->credentials->getCallbackUrl(),
-        'response_type' => 'code',
-        'client_id' => $consumer_key,
-      ];
-
-      // Send the user along to the Salesforce OAuth login form. If successful,
-      // the user will be redirected to {redirect_uri} to complete the OAuth
-      // handshake, and thence to the entity listing. Upon failure, the user
-      // redirect URI will send the user back to the edit form.
-      $response = new TrustedRedirectResponse($path . '?' . http_build_query($query), 302);
-      $response->send();
-      return;
-    }
-    catch (\Exception $e) {
-      $this->messenger()->addError(t("Error during authorization: %message", ['%message' => $e->getMessage()]));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function decrypt($value) {
-    return $this->encryption->decrypt($value, $this->encryptionProfile());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function encrypt($value) {
-    return $this->encryption->encrypt($value, $this->encryptionProfile());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConsumerSecret() {
-    return $this->credentials->getConsumerSecret();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function finalizeOauth() {
-    $this->requestAccessToken(\Drupal::request()->get('code'));
-    $token = $this->getAccessToken();
-
-    // Initialize identity.
-    $headers = [
-      'Authorization' => 'OAuth ' . $token->getAccessToken(),
-      'Content-type' => 'application/json',
-    ];
-    $data = $token->getExtraParams();
-    $response = $this->httpClient->retrieveResponse(new Uri($data['id']), [], $headers);
-    $identity = $this->parseIdentityResponse($response);
-    $this->storage->storeIdentity($this->service(), $identity);
-    return TRUE;
-  }
-
-}
diff --git a/modules/salesforce_encrypt/src/SalesforceEncrypt.php b/modules/salesforce_encrypt/src/SalesforceEncrypt.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb468e940d96397bab94ddd5112326992c3c6891
--- /dev/null
+++ b/modules/salesforce_encrypt/src/SalesforceEncrypt.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Drupal\salesforce_encrypt;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\State\StateInterface;
+use Drupal\encrypt\EncryptionProfileManagerInterface;
+use Drupal\key\KeyConfigOverrides;
+use Drupal\salesforce\Entity\SalesforceAuthConfig;
+
+class SalesforceEncrypt {
+
+
+
+  public function __construct(EncryptionProfileManagerInterface $encryptionProfileManager, KeyConfigOverrides $keyConfigOverrides, ConfigFactoryInterface $configFactory, StateInterface $state) {
+    $this->encryptionProfileManager = $encryptionProfileManager;
+    $this->keyConfigOverrides = $keyConfigOverrides;
+    $this->configFactory = $configFactory;
+    $this->state = $state;
+  }
+
+  /**
+   * TRUE if the given authconfig is overridden with encrypted values.
+   *
+   * @param \Drupal\salesforce\Entity\SalesforceAuthConfig $authConfig
+   *   The given auth config.
+   *
+   * @return bool
+   *   TRUE if the given authconfig is overridden with encrypted values.
+   */
+  public function isEncrypted(SalesforceAuthConfig $auth) {
+    $config = $this->configFactory->get($auth->getConfigDependencyName());
+    // If it's not overridden, we know it's not encrypted.
+    if (!$config->hasOverrides()) {
+      return FALSE;
+    }
+    // If it's overridden, see if it's an encrypted config.
+    // @TODO write me
+    $this->keyConfigOverrides->loadOverrides()
+  }
+
+  /**
+   * Get the assigned encryption profile, or NULL.
+   *
+   * @return \Drupal\encrypt\EncryptionProfileInterface|NULL
+   *   The assigned encryption profile, or NULL.
+   */
+  public function getProfile() {
+    $profileId = $this->getProfileId();
+    return $this->encryptionProfileManager->getEncryptionProfile($profileId);
+  }
+
+  /**
+   * Get the assigned encryption profile id, or NULL.
+   *
+   * @return string|NULL
+   *   The assigned encryption profile id, or NULL.
+   */
+  public function getProfileId() {
+    return $this->state->get('salesforce_encrypt.profile');
+  }
+
+
+}
\ No newline at end of file
diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php b/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..e75e85b08b4d92b5476cbdab97e1ab84a43d3936
--- /dev/null
+++ b/modules/salesforce_encrypt/src/SalesforceEncryptServiceProvider.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\salesforce_encrypt;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Alter the container to include our own storage providers.
+ */
+class SalesforceEncryptServiceProvider {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alter(ContainerBuilder $container) {
+    // Add a normalizer service for file entities.
+    $service_definition = new Definition('Drupal\salesforce_encrypt\Storage\SalesforceEncryptedAuthTokenStorage', array(
+      new Reference('state'),
+      new Reference('encryption'),
+      new Reference('encrypt.encryption_profile.manager'),
+    ));
+    $container->setDefinition('salesforce.auth_token_storage', $service_definition);
+  }
+
+}
diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php b/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php
deleted file mode 100644
index 6ff4be197a6c375408d9161a9976cbe9d19d51f2..0000000000000000000000000000000000000000
--- a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorageInterface.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\salesforce_encrypt;
-
-use Drupal\salesforce\Storage\SalesforceAuthTokenStorageInterface;
-
-/**
- * Encrypted token storage interface.
- */
-interface SalesforceEncryptedAuthTokenStorageInterface extends SalesforceAuthTokenStorageInterface {
-
-}
diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php b/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php
deleted file mode 100644
index 27a94f22ca80fdde2fd123674b14f3a7c4595b4b..0000000000000000000000000000000000000000
--- a/modules/salesforce_encrypt/src/SalesforceEncryptedOAuthPluginInterface.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-namespace Drupal\salesforce_encrypt;
-
-use Drupal\encrypt\EncryptionProfileInterface;
-use Drupal\salesforce\SalesforceOAuthPluginInterface;
-
-/**
- * Encrypted oauth provider interface.
- */
-interface SalesforceEncryptedOAuthPluginInterface extends SalesforceOAuthPluginInterface {
-
-  /**
-   * Callback for hook_encryption_profile_predelete().
-   *
-   * @param \Drupal\encrypt\EncryptionProfileInterface $profile
-   *   The encryption profile being deleted.
-   */
-  public function hookEncryptionProfileDelete(EncryptionProfileInterface $profile);
-
-  /**
-   * Get the encryption profile assigned to this auth plugin.
-   *
-   * @return \Drupal\encrypt\EncryptionProfileInterface|null
-   *   Profile.
-   */
-  public function encryptionProfile();
-
-  /**
-   * Decrypt a given value, using the assigned encryption profile.
-   *
-   * @param string $value
-   *   The encrypted value.
-   *
-   * @return string
-   *   The plain text value.
-   *
-   * @throws \Drupal\encrypt\Exception\EncryptException
-   *   On decryption error.
-   */
-  public function decrypt($value);
-
-  /**
-   * Encrypt a value, using the assigned encryption profile.
-   *
-   * @param string $value
-   *   The plain text value.
-   *
-   * @return string
-   *   The encrypted value.
-   *
-   * @throws \Drupal\encrypt\Exception\EncryptException
-   *   On error.
-   */
-  public function encrypt($value);
-
-}
diff --git a/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..e712e436064685d861804a8b6b4a3fcfa47c2da4
--- /dev/null
+++ b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthStorage.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\salesforce_encrypt\Storage;
+
+use Drupal\Core\Config\Entity\ConfigEntityStorage;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityMalformedException;
+
+class SalesforceEncryptedAuthStorage extends ConfigEntityStorage {
+
+  /**
+   * Implements Drupal\Core\Entity\EntityStorageInterface::save().
+   *
+   * @throws EntityMalformedException
+   *   When attempting to save a configuration entity that has no ID.
+   */
+  public function save(EntityInterface $entity) {
+    // Encrypt the sensitive values and hand off to parent.
+    return parent::save($entity);
+  }
+
+  protected function doLoadMultiple(array $ids = NULL) {
+    $entities = parent::doLoadMultiple($ids);
+    // Decrypt the sensitive values and return
+    return $entities;
+  }
+
+
+}
\ No newline at end of file
diff --git a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php
similarity index 72%
rename from modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php
rename to modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php
index 53252719adc918ff7dfd6e44b19e9cf9565b78c8..7b4bef26c65f307ac7c95a577077c50c891f8b87 100644
--- a/modules/salesforce_encrypt/src/SalesforceEncryptedAuthTokenStorage.php
+++ b/modules/salesforce_encrypt/src/Storage/SalesforceEncryptedAuthTokenStorage.php
@@ -1,16 +1,14 @@
 <?php
 
-namespace Drupal\salesforce_encrypt;
+namespace Drupal\salesforce_encrypt\Storage;
 
-use Drupal\salesforce\Entity\SalesforceAuthConfig;
 use Drupal\salesforce\Storage\SalesforceAuthTokenStorage;
-use Drupal\salesforce_encrypt\Plugin\SalesforceAuthProvider\SalesforceEncryptedOAuthPlugin;
 use OAuth\Common\Token\TokenInterface;
 
 /**
  * Auth token storage, using encryption.
  */
-class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage implements SalesforceEncryptedAuthTokenStorageInterface {
+class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage {
 
   /**
    * Auth plugin manager.
@@ -19,23 +17,6 @@ class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage imp
    */
   protected $authPluginManager;
 
-  /**
-   * Given a service id, return the instantiated auth provider plugin.
-   *
-   * @param string $service_id
-   *   The service id.
-   *
-   * @return \Drupal\salesforce\SalesforceAuthProviderInterface
-   *   The plugin.
-   */
-  protected function service($service_id) {
-    if (!$this->authPluginManager) {
-      $this->authPluginManager = \Drupal::service('plugin.manager.salesforce.auth_providers');
-    }
-    $auth = SalesforceAuthConfig::load($service_id);
-    return $auth->getPlugin();
-  }
-
   /**
    * {@inheritdoc}
    */
@@ -88,4 +69,8 @@ class SalesforceEncryptedAuthTokenStorage extends SalesforceAuthTokenStorage imp
     return $identity;
   }
 
+  public function storeAuthorizationState($service, $state) {
+    return parent::storeAuthorizationState($service, $state); // TODO: Change the autogenerated stub
+  }
+
 }
diff --git a/modules/salesforce_jwt/salesforce_jwt.info.yml b/modules/salesforce_jwt/salesforce_jwt.info.yml
index 040a7403776d9e8109fe4d06e7a6f16f3095f976..d5a85f8f7c46d7c7ed514fb1d6a3523616089dd3 100644
--- a/modules/salesforce_jwt/salesforce_jwt.info.yml
+++ b/modules/salesforce_jwt/salesforce_jwt.info.yml
@@ -4,5 +4,5 @@ description: Provides key-based Salesforce authentication.
 core: 8.x
 package: Salesforce
 dependencies:
-  - salesforce
-  - key
+  - salesforce:salesforce
+  - key:key
diff --git a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php
index 24f5f6884a925272855a602613144455439c18d8..6e75639b4f654bb6acd43d7af7502b16d5559e84 100644
--- a/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php
+++ b/modules/salesforce_jwt/src/Plugin/SalesforceAuthProvider/SalesforceJWTPlugin.php
@@ -60,11 +60,6 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase {
     $this->id = $id;
   }
 
-  public function getConsumerSecret() {
-    return parent::getConsumerSecret(); // TODO: Change the autogenerated stub
-  }
-
-
   /**
    * {@inheritdoc}
    */
@@ -284,4 +279,11 @@ class SalesforceJWTPlugin extends SalesforceAuthProviderPluginBase {
     ];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function finalizeOauth() {
+    // Not used. Implemented for interface compatibility only.
+  }
+
 }
diff --git a/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php b/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php
index b6f67cfae320550e4f5c82c38dcbdc4e1f0230a1..dbe6bae8b7543cf383781d2929270e8214496cde 100644
--- a/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php
+++ b/modules/salesforce_oauth/src/Plugin/SalesforceAuthProvider/SalesforceOAuthPlugin.php
@@ -19,8 +19,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   id = "oauth",
  *   label = @Translation("Salesforce OAuth User-Agent")
  * )
- *
- * @deprecated BC legacy auth scheme only. will be removed in 8.x-4.0.
  */
 class SalesforceOAuthPlugin extends SalesforceAuthProviderPluginBase implements SalesforceAuthProviderInterface {
 
diff --git a/salesforce.info.yml b/salesforce.info.yml
index c6a3d3f05d2a9799f1d1c2ada1ec48bb183082cc..5efe50b742413824805020456f8bea99d8c9b251 100644
--- a/salesforce.info.yml
+++ b/salesforce.info.yml
@@ -4,3 +4,5 @@ description: Modules to integrate Drupal and Salesforce
 package: Salesforce
 core: 8.x
 configure: salesforce.admin_config_salesforce
+dependencies:
+  typed_data:typed_data
\ No newline at end of file
diff --git a/salesforce.install b/salesforce.install
index 46da9e73e5121bdb84e8ca777ab42395b20fc4ed..87afd6702c4584fe584dbed7a97794faa573f1ab 100644
--- a/salesforce.install
+++ b/salesforce.install
@@ -69,13 +69,13 @@ function salesforce_get_auth_provider_requirements() {
   if (!$authMan->hasProviders()) {
     $requirements += [
       'description' => t('No auth providers have been created. Please <a href="@href">create an auth provider</a> to connect to Salesforce.', ['@href' => Url::fromRoute('entity.salesforce_auth.add_form')]),
-      'severity' => REQUIREMENT_WARNING,
+      'severity' => REQUIREMENT_ERROR,
     ];
   }
   elseif (!$authMan->getConfig()) {
     $requirements += [
       'description' => t('Default auth provider has not been set. Please <a href="@href">choose an auth provider</a> to connect to Salesforce.', ['@href' => Url::fromRoute('salesforce.auth_config')->toString()]),
-      'severity' => REQUIREMENT_WARNING,
+      'severity' => REQUIREMENT_ERROR,
     ];
   }
   else {
@@ -84,14 +84,14 @@ function salesforce_get_auth_provider_requirements() {
       if (!$authMan->getToken()) {
         $requirements += [
           'description' => $failMessage,
-          'severity' => REQUIREMENT_WARNING,
+          'severity' => REQUIREMENT_ERROR,
         ];
       }
     }
     catch (Exception $e) {
       $requirements += [
         'description' => $failMessage,
-        'severity' => REQUIREMENT_WARNING,
+        'severity' => REQUIREMENT_ERROR,
       ];
     }
   }
diff --git a/salesforce.links.action.yml b/salesforce.links.action.yml
index f9d6829e9934c6ed3cdccecc7fbc10cc43f545a4..30ba3189d150880043c31c362557f37a0779a675 100644
--- a/salesforce.links.action.yml
+++ b/salesforce.links.action.yml
@@ -5,10 +5,3 @@ salesforce_auth.add_action:
     - entity.salesforce_auth.collection
     - entity.salesforce_auth.edit_form
     - salesforce.auth_config
-
-salesforce_auth.list_action:
-  route_name: entity.salesforce_auth.collection
-  title: 'Salesforce Auth Provider List'
-  appears_on:
-    - entity.salesforce_auth.add_form
-    - entity.salesforce_auth.edit_form
diff --git a/salesforce.links.task.yml b/salesforce.links.task.yml
index f2715a9190f5ba9da1b07ccb11ee906f7c18baf0..bcbe6f27eed9b18669ae6af97ed3822570bd0441 100644
--- a/salesforce.links.task.yml
+++ b/salesforce.links.task.yml
@@ -7,3 +7,18 @@ entity.salesforce_auth.collection:
   route_name: entity.salesforce_auth.collection
   base_route: salesforce.auth_config
   title: 'Providers'
+
+entity.salesforce_auth.edit_form:
+  route_name: entity.salesforce_auth.edit_form
+  base_route: entity.salesforce_auth.edit_form
+  title: 'Edit'
+
+entity.salesforce_auth.revoke:
+  route_name: entity.salesforce_auth.revoke
+  base_route: entity.salesforce_auth.edit_form
+  title: 'Revoke'
+
+entity.salesforce_auth.delete_form:
+  route_name: entity.salesforce_auth.delete_form
+  base_route: entity.salesforce_auth.edit_form
+  title: 'Delete'
diff --git a/src/Controller/SalesforceAuthListBuilder.php b/src/Controller/SalesforceAuthListBuilder.php
index 0937ebe7643f6b3f0cd4d842910c48810c32c3ad..f40c45f7b3b83142fc98d97e41da0a7072c35b64 100644
--- a/src/Controller/SalesforceAuthListBuilder.php
+++ b/src/Controller/SalesforceAuthListBuilder.php
@@ -4,6 +4,8 @@ namespace Drupal\salesforce\Controller;
 
 use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\salesforce\Entity\SalesforceAuthConfig;
+use Drupal\salesforce\SalesforceAuthProviderInterface;
 
 /**
  * List builder for salesforce_auth.
@@ -20,9 +22,30 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder {
     $row['url'] = $plugin->getLoginUrl();
     $row['key'] = substr($plugin->getConsumerKey(), 0, 16) . '...';
     $row['type'] = $plugin->label();
+    $row['status'] = $plugin->hasAccessToken() ? 'Authorized' : 'Missing';
     return $row + parent::buildRow($entity);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultOperations(EntityInterface $entity) {
+    $operations = parent::getDefaultOperations($entity);
+    $operations['edit']['title'] = t('Edit / Re-auth');
+    if (!$entity instanceof SalesforceAuthConfig
+    || !$entity->getPlugin()->hasAccessToken()
+    || !$entity->hasLinkTemplate('revoke')) {
+      return $operations;
+    }
+    // Add a "revoke" action if we have a token.
+    $operations['revoke'] = [
+      'title' => t('Revoke'),
+      'weight' => 20,
+      'url' => $this->ensureDestination($entity->toUrl('revoke')),
+    ];
+    return $operations;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -39,6 +62,9 @@ class SalesforceAuthListBuilder extends ConfigEntityListBuilder {
     $header['type'] = [
       'data' => $this->t('Auth Type'),
     ];
+    $header['status'] = [
+      'data' => $this->t('Token Status'),
+    ];
 
     return $header + parent::buildHeader();
   }
diff --git a/src/Form/SalesforceAuthForm.php b/src/Form/SalesforceAuthForm.php
index 21eb56104a391737373ac8b56b5d54f49133bdb3..42bc8fe4e2dc6c3a97d79958a17e20c7f376300f 100644
--- a/src/Form/SalesforceAuthForm.php
+++ b/src/Form/SalesforceAuthForm.php
@@ -19,11 +19,15 @@ class SalesforceAuthForm extends EntityForm {
    */
   protected $entity;
 
+
+
   /**
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
     $auth = $this->entity;
+    $form_state->setBuildInfo($form_state->getBuildInfo()
+      + ['auth_config' => $this->config($auth->getConfigDependencyName())]);
     $form['label'] = [
       '#title' => $this->t('Label'),
       '#type' => 'textfield',
diff --git a/src/Form/SalesforceAuthRevokeForm.php b/src/Form/SalesforceAuthRevokeForm.php
index a69b21c5086a7fa9fee8c2f0dadb6ef7952960b7..4463ba9a135be0ac8233d2b6c7ba104ca11ed728 100644
--- a/src/Form/SalesforceAuthRevokeForm.php
+++ b/src/Form/SalesforceAuthRevokeForm.php
@@ -5,13 +5,14 @@ namespace Drupal\salesforce\Form;
 use Drupal\Core\Entity\EntityConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\salesforce\Entity\SalesforceAuthConfig;
 
-class AuthConfigDeleteForm extends EntityConfirmFormBase {
+class SalesforceAuthRevokeForm extends EntityConfirmFormBase {
   /**
    * {@inheritdoc}
    */
   public function getQuestion() {
-    return $this->t('Are you sure you want to delete the Auth Config %name?', ['%name' => $this->entity->label()]);
+    return $this->t('Are you sure you want to revoke authorization for Auth Config %name?', ['%name' => $this->entity->label()]);
   }
 
   /**
@@ -25,17 +26,20 @@ class AuthConfigDeleteForm extends EntityConfirmFormBase {
    * {@inheritdoc}
    */
   public function getConfirmText() {
-    return $this->t('Delete');
+    return $this->t('Revoke Auth Token');
   }
 
   /**
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->entity->delete();
+    if (!$this->entity instanceof SalesforceAuthConfig) {
+      return;
+    }
+    $this->entity->getPlugin()->revokeAccessToken();
 
     // Set a message that the entity was deleted.
-    $this->messenger()->addStatus($this->t('Auth Config %label was deleted.', [
+    $this->messenger()->addStatus($this->t('Auth token for %label was revoked.', [
       '%label' => $this->entity->label(),
     ]));
 
diff --git a/src/Rest/RestClient.php b/src/Rest/RestClient.php
index c9df7ec1af6cff83f244bf3d707542c010cda5b6..a07f6d41718f7c625446f1a7c6fae598d2b25b16 100644
--- a/src/Rest/RestClient.php
+++ b/src/Rest/RestClient.php
@@ -217,7 +217,7 @@ class RestClient implements RestClientInterface {
    * @throws \GuzzleHttp\Exception\RequestException
    */
   protected function apiHttpRequest($url, array $params, $method) {
-    if (!$this->authManager->getToken()) {
+    if (!$this->authToken) {
       throw new \Exception('Missing OAuth Token');
     }
 
diff --git a/src/SalesforceAuthProviderInterface.php b/src/SalesforceAuthProviderInterface.php
index aee8ea850900a5363e1333613d54999a568305a4..1de98b87ca3180b2e01efce1b0320ad348df98bf 100644
--- a/src/SalesforceAuthProviderInterface.php
+++ b/src/SalesforceAuthProviderInterface.php
@@ -107,6 +107,13 @@ interface SalesforceAuthProviderInterface extends ServiceInterface, PluginFormIn
    */
   public function hasAccessToken();
 
+  /**
+   * Clear the access token for this auth provider plugin.
+   *
+   * @return $this
+   */
+  public function revokeAccessToken();
+
   /**
    * Default configuration for this plugin type.
    *
diff --git a/src/SalesforceAuthProviderPluginBase.php b/src/SalesforceAuthProviderPluginBase.php
index a0580ac90b07e29274f152d77442b0bb4930148c..f1d7f4ac9d73494a64f886efa3b3089c973b82bc 100644
--- a/src/SalesforceAuthProviderPluginBase.php
+++ b/src/SalesforceAuthProviderPluginBase.php
@@ -3,12 +3,14 @@
 namespace Drupal\salesforce;
 
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
+use Drupal\Core\Form\ConfigFormBaseTrait;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Messenger\MessengerTrait;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use OAuth\Common\Http\Exception\TokenResponseException;
 use OAuth\Common\Http\Uri\Uri;
 use OAuth\OAuth2\Service\Salesforce;
+use Symfony\Component\DependencyInjection\Loader\Configurator\Traits\FactoryTrait;
 
 /**
  * Shared methods for auth providers.
@@ -179,6 +181,13 @@ abstract class SalesforceAuthProviderPluginBase extends Salesforce implements Sa
     return $this->storage->retrieveAccessToken($this->id());
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function revokeAccessToken() {
+    return $this->storage->clearToken($this->id());
+  }
+
   /**
    * {@inheritdoc}
    */