diff --git a/src/DeviceListener.js b/src/DeviceListener.js
index 21c844e11c..3201e4af45 100644
--- a/src/DeviceListener.js
+++ b/src/DeviceListener.js
@@ -124,7 +124,7 @@ export default class DeviceListener {
         const cli = MatrixClientPeg.get();
 
         if (
-            !SettingsStore.isFeatureEnabled("feature_cross_signing") ||
+            !SettingsStore.getValue("feature_cross_signing") ||
             !await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")
         ) return;
 
diff --git a/src/KeyRequestHandler.js b/src/KeyRequestHandler.js
index 30f3b7d50e..ceaff0c54d 100644
--- a/src/KeyRequestHandler.js
+++ b/src/KeyRequestHandler.js
@@ -35,7 +35,7 @@ export default class KeyRequestHandler {
 
     handleKeyRequest(keyRequest) {
         // Ignore own device key requests if cross-signing lab enabled
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             return;
         }
 
@@ -70,7 +70,7 @@ export default class KeyRequestHandler {
 
     handleKeyRequestCancellation(cancellation) {
         // Ignore own device key requests if cross-signing lab enabled
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             return;
         }
 
diff --git a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
index 3a480a2579..55419cecff 100644
--- a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
+++ b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
@@ -77,7 +77,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
     async componentDidMount() {
         const cli = MatrixClientPeg.get();
         const secureSecretStorage = (
-            SettingsStore.isFeatureEnabled("feature_cross_signing") &&
+            SettingsStore.getValue("feature_cross_signing") &&
             await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")
         );
         this.setState({ secureSecretStorage });
diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index 519b39d436..1293ccc7e9 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -1506,7 +1506,7 @@ export default createReactClass({
         });
 
         cli.on("crypto.verification.request", request => {
-            const isFlagOn = SettingsStore.isFeatureEnabled("feature_cross_signing");
+            const isFlagOn = SettingsStore.getValue("feature_cross_signing");
 
             if (!isFlagOn && !request.channel.deviceId) {
                 request.cancel({code: "m.invalid_message", reason: "This client has cross-signing disabled"});
@@ -1556,7 +1556,7 @@ export default createReactClass({
             // changing colour. More advanced behaviour will come once
             // we implement more settings.
             cli.setGlobalErrorOnUnknownDevices(
-                !SettingsStore.isFeatureEnabled("feature_cross_signing"),
+                !SettingsStore.getValue("feature_cross_signing"),
             );
         }
     },
@@ -1921,10 +1921,10 @@ export default createReactClass({
         if (masterKeyInStorage) {
             // Auto-enable cross-signing for the new session when key found in
             // secret storage.
-            SettingsStore.setFeatureEnabled("feature_cross_signing", true);
+            SettingsStore.setValue("feature_cross_signing", null, SettingLevel.DEVICE, true);
             this.setStateForNewView({ view: VIEWS.COMPLETE_SECURITY });
         } else if (
-            SettingsStore.isFeatureEnabled("feature_cross_signing") &&
+            SettingsStore.getValue("feature_cross_signing") &&
             await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")
         ) {
             // This will only work if the feature is set to 'enable' in the config,
diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js
index 3c97d2f4ae..f5bdfdf40d 100644
--- a/src/components/structures/RightPanel.js
+++ b/src/components/structures/RightPanel.js
@@ -219,7 +219,7 @@ export default class RightPanel extends React.Component {
                 break;
             case RIGHT_PANEL_PHASES.RoomMemberInfo:
             case RIGHT_PANEL_PHASES.EncryptionPanel:
-                if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+                if (SettingsStore.getValue("feature_cross_signing")) {
                     const onClose = () => {
                         dis.dispatch({
                             action: "view_user",
@@ -246,7 +246,7 @@ export default class RightPanel extends React.Component {
                 panel = <ThirdPartyMemberInfo event={this.state.event} key={this.props.roomId} />;
                 break;
             case RIGHT_PANEL_PHASES.GroupMemberInfo:
-                if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+                if (SettingsStore.getValue("feature_cross_signing")) {
                     const onClose = () => {
                         dis.dispatch({
                             action: "view_user",
diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js
index 78bd34bf7f..179e0aa2e9 100644
--- a/src/components/structures/RoomView.js
+++ b/src/components/structures/RoomView.js
@@ -822,7 +822,7 @@ export default createReactClass({
             });
             return;
         }
-        if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!SettingsStore.getValue("feature_cross_signing")) {
             room.hasUnverifiedDevices().then((hasUnverifiedDevices) => {
                 this.setState({
                     e2eStatus: hasUnverifiedDevices ? "warning" : "verified",
diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js
index f18e28b85e..fa8c7dd30e 100644
--- a/src/components/views/dialogs/CreateRoomDialog.js
+++ b/src/components/views/dialogs/CreateRoomDialog.js
@@ -65,7 +65,7 @@ export default createReactClass({
             createOpts.creation_content = {'m.federate': false};
         }
 
-        if (!this.state.isPublic && SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!this.state.isPublic && SettingsStore.getValue("feature_cross_signing")) {
             opts.encryption = this.state.isEncrypted;
         }
 
@@ -192,7 +192,7 @@ export default createReactClass({
         }
 
         let e2eeSection;
-        if (!this.state.isPublic && SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!this.state.isPublic && SettingsStore.getValue("feature_cross_signing")) {
             e2eeSection = <React.Fragment>
                 <LabelledToggleSwitch label={ _t("Enable end-to-end encryption")} onChange={this.onEncryptedChange} value={this.state.isEncrypted} />
                 <p>{ _t("You can’t disable this later. Bridges & most bots won’t work yet.") }</p>
diff --git a/src/components/views/dialogs/DeviceVerifyDialog.js b/src/components/views/dialogs/DeviceVerifyDialog.js
index 39e391269c..a3f9430476 100644
--- a/src/components/views/dialogs/DeviceVerifyDialog.js
+++ b/src/components/views/dialogs/DeviceVerifyDialog.js
@@ -131,7 +131,7 @@ export default class DeviceVerifyDialog extends React.Component {
                 } else {
                     this._verifier = request.verifier;
                 }
-            } else if (verifyingOwnDevice && SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+            } else if (verifyingOwnDevice && SettingsStore.getValue("feature_cross_signing")) {
                 this._request = await client.requestVerification(this.props.userId, [
                     verificationMethods.SAS,
                     SHOW_QR_CODE_METHOD,
diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js
index f0d5443cac..a46fa0df07 100644
--- a/src/components/views/dialogs/InviteDialog.js
+++ b/src/components/views/dialogs/InviteDialog.js
@@ -574,7 +574,7 @@ export default class InviteDialog extends React.PureComponent {
 
         const createRoomOptions = {inlineErrors: true};
 
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             // Check whether all users have uploaded device keys before.
             // If so, enable encryption in the new room.
             const client = MatrixClientPeg.get();
diff --git a/src/components/views/messages/MessageActionBar.js b/src/components/views/messages/MessageActionBar.js
index 5516ff2146..0cde90e417 100644
--- a/src/components/views/messages/MessageActionBar.js
+++ b/src/components/views/messages/MessageActionBar.js
@@ -49,7 +49,7 @@ const OptionsButton = ({mxEvent, getTile, getReplyThread, permalinkCreator, onFo
         };
 
         let e2eInfoCallback = null;
-        if (mxEvent.isEncrypted() && !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (mxEvent.isEncrypted() && !SettingsStore.getValue("feature_cross_signing")) {
             e2eInfoCallback = onCryptoClick;
         }
 
diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js
index abe54b355e..862e4f7897 100644
--- a/src/components/views/right_panel/UserInfo.js
+++ b/src/components/views/right_panel/UserInfo.js
@@ -63,7 +63,7 @@ const _disambiguateDevices = (devices) => {
 };
 
 export const getE2EStatus = (cli, userId, devices) => {
-    if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+    if (!SettingsStore.getValue("feature_cross_signing")) {
         const hasUnverifiedDevice = devices.some((device) => device.isUnverified());
         return hasUnverifiedDevice ? "warning" : "verified";
     }
@@ -111,7 +111,7 @@ async function openDMForUser(matrixClient, userId) {
         dmUserId: userId,
     };
 
-    if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+    if (SettingsStore.getValue("feature_cross_signing")) {
         // Check whether all users have uploaded device keys before.
         // If so, enable encryption in the new room.
         const usersToDevicesMap = await matrixClient.downloadKeys([userId]);
@@ -166,7 +166,7 @@ function DeviceItem({userId, device}) {
     // cross-signing so that other users can then safely trust you.
     // For other people's devices, the more general verified check that
     // includes locally verified devices can be used.
-    const isVerified = (isMe && SettingsStore.isFeatureEnabled("feature_cross_signing")) ?
+    const isVerified = (isMe && SettingsStore.getValue("feature_cross_signing")) ?
         deviceTrust.isCrossSigningVerified() :
         deviceTrust.isVerified();
 
@@ -237,7 +237,7 @@ function DevicesSection({devices, userId, loading}) {
             // cross-signing so that other users can then safely trust you.
             // For other people's devices, the more general verified check that
             // includes locally verified devices can be used.
-            const isVerified = (isMe && SettingsStore.isFeatureEnabled("feature_cross_signing")) ?
+            const isVerified = (isMe && SettingsStore.getValue("feature_cross_signing")) ?
                 deviceTrust.isCrossSigningVerified() :
                 deviceTrust.isVerified();
 
@@ -1298,7 +1298,7 @@ const BasicUserInfo = ({room, member, groupId, devices, isRoomEncrypted}) => {
     const userTrust = cli.checkUserTrust(member.userId);
     const userVerified = userTrust.isCrossSigningVerified();
     const isMe = member.userId === cli.getUserId();
-    const canVerify = SettingsStore.isFeatureEnabled("feature_cross_signing") &&
+    const canVerify = SettingsStore.getValue("feature_cross_signing") &&
                         homeserverSupportsCrossSigning && !userVerified && !isMe;
 
     const setUpdating = (updating) => {
diff --git a/src/components/views/rooms/E2EIcon.js b/src/components/views/rooms/E2EIcon.js
index a2c99fad99..9189cfdf26 100644
--- a/src/components/views/rooms/E2EIcon.js
+++ b/src/components/views/rooms/E2EIcon.js
@@ -20,7 +20,7 @@ import PropTypes from "prop-types";
 import classNames from 'classnames';
 
 import {_t, _td} from '../../../languageHandler';
-import {useFeatureEnabled} from "../../../hooks/useSettings";
+import {useFeatureEnabled, useSettingValue} from "../../../hooks/useSettings";
 import AccessibleButton from "../elements/AccessibleButton";
 import Tooltip from "../elements/Tooltip";
 
@@ -62,7 +62,7 @@ const E2EIcon = ({isUser, status, className, size, onClick, hideTooltip}) => {
     }, className);
 
     let e2eTitle;
-    const crossSigning = useFeatureEnabled("feature_cross_signing");
+    const crossSigning = useSettingValue("feature_cross_signing");
     if (crossSigning && isUser) {
         e2eTitle = crossSigningUserTitles[status];
     } else if (crossSigning && !isUser) {
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index 75fbe5caa3..f67877373e 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -323,7 +323,7 @@ export default createReactClass({
 
         // If cross-signing is off, the old behaviour is to scream at the user
         // as if they've done something wrong, which they haven't
-        if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!SettingsStore.getValue("feature_cross_signing")) {
             this.setState({
                 verified: E2E_STATE.WARNING,
             }, this.props.onHeightChanged);
diff --git a/src/components/views/rooms/MemberTile.js b/src/components/views/rooms/MemberTile.js
index bf2a1bee23..d830624f8a 100644
--- a/src/components/views/rooms/MemberTile.js
+++ b/src/components/views/rooms/MemberTile.js
@@ -56,7 +56,7 @@ export default createReactClass({
             }
         }
 
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             const { roomId } = this.props.member;
             if (roomId) {
                 const isRoomEncrypted = cli.isRoomEncrypted(roomId);
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js
index c86bcb2ff0..4749742a7d 100644
--- a/src/components/views/rooms/MessageComposer.js
+++ b/src/components/views/rooms/MessageComposer.js
@@ -270,7 +270,7 @@ export default class MessageComposer extends React.Component {
     }
 
     renderPlaceholderText() {
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             if (this.state.isQuoting) {
                 if (this.props.e2eStatus) {
                     return _t('Send an encrypted reply…');
diff --git a/src/components/views/rooms/RoomBreadcrumbs.js b/src/components/views/rooms/RoomBreadcrumbs.js
index 1d433c9a40..09228c454b 100644
--- a/src/components/views/rooms/RoomBreadcrumbs.js
+++ b/src/components/views/rooms/RoomBreadcrumbs.js
@@ -364,7 +364,7 @@ export default class RoomBreadcrumbs extends React.Component {
             }
 
             let dmIndicator;
-            if (this._isDmRoom(r.room) && !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+            if (this._isDmRoom(r.room) && !SettingsStore.getValue("feature_cross_signing")) {
                 dmIndicator = <img
                     src={require("../../../../res/img/icon_person.svg")}
                     className="mx_RoomBreadcrumbs_dmIndicator"
diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js
index 71f774248f..17495e6299 100644
--- a/src/components/views/rooms/RoomHeader.js
+++ b/src/components/views/rooms/RoomHeader.js
@@ -168,7 +168,7 @@ export default createReactClass({
         const joinRule = joinRules && joinRules.getContent().join_rule;
         let privateIcon;
         // Don't show an invite-only icon for DMs. Users know they're invite-only.
-        if (!dmUserId && SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!dmUserId && SettingsStore.getValue("feature_cross_signing")) {
             if (joinRule == "invite") {
                 privateIcon = <InviteOnlyIcon />;
             }
diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js
index d264b087a0..a34ade365b 100644
--- a/src/components/views/rooms/RoomTile.js
+++ b/src/components/views/rooms/RoomTile.js
@@ -155,7 +155,7 @@ export default createReactClass({
         if (!cli.isRoomEncrypted(this.props.room.roomId)) {
             return;
         }
-        if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (!SettingsStore.getValue("feature_cross_signing")) {
             return;
         }
 
@@ -488,7 +488,7 @@ export default createReactClass({
         let dmOnline;
         /* Post-cross-signing we don't show DM indicators at all, instead relying on user
            context to let them know when that is. */
-        if (dmUserId && !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (dmUserId && !SettingsStore.getValue("feature_cross_signing")) {
             dmIndicator = <img
                 src={require("../../../../res/img/icon_person.svg")}
                 className="mx_RoomTile_dm"
@@ -532,7 +532,7 @@ export default createReactClass({
         }
 
         let privateIcon = null;
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             if (this.state.joinRule == "invite" && !dmUserId) {
                 privateIcon = <InviteOnlyIcon collapsedPanel={this.props.collapsed} />;
             }
diff --git a/src/components/views/settings/KeyBackupPanel.js b/src/components/views/settings/KeyBackupPanel.js
index 9d60ed1188..5548768221 100644
--- a/src/components/views/settings/KeyBackupPanel.js
+++ b/src/components/views/settings/KeyBackupPanel.js
@@ -326,7 +326,7 @@ export default class KeyBackupPanel extends React.PureComponent {
                     </AccessibleButton>
                 </div>
             );
-            if (this.state.backupKeyStored && !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+            if (this.state.backupKeyStored && !SettingsStore.getValue("feature_cross_signing")) {
                 buttonRow = <p>⚠️ {_t(
                     "Backup key stored in secret storage, but this feature is not " +
                     "enabled on this session. Please enable cross-signing in Labs to " +
diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
index 3e69107159..fe160032ff 100644
--- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
@@ -62,6 +62,7 @@ export default class LabsUserSettingsTab extends React.Component {
                 </div>
                 <div className="mx_SettingsTab_section">
                     {flags}
+                    <SettingsFlag name={"feature_cross_signing"} level={SettingLevel.DEVICE} />
                     <SettingsFlag name={"enableWidgetScreenshots"} level={SettingLevel.ACCOUNT} />
                     <SettingsFlag name={"showHiddenEventsInTimeline"} level={SettingLevel.DEVICE} />
                     <SettingsFlag name={"lowBandwidth"} level={SettingLevel.DEVICE} />
diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js
index 3dca6e2490..1cde5d6f87 100644
--- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js
@@ -270,7 +270,7 @@ export default class SecurityUserSettingsTab extends React.Component {
         // can remove this.
         const CrossSigningPanel = sdk.getComponent('views.settings.CrossSigningPanel');
         let crossSigning;
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             crossSigning = (
                 <div className='mx_SettingsTab_section'>
                     <span className="mx_SettingsTab_subheading">{_t("Cross-signing")}</span>
diff --git a/src/createRoom.js b/src/createRoom.js
index 66d4d1908e..a39d2c2216 100644
--- a/src/createRoom.js
+++ b/src/createRoom.js
@@ -227,7 +227,7 @@ export async function ensureDMExists(client, userId) {
         roomId = existingDMRoom.roomId;
     } else {
         let encryption;
-        if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+        if (SettingsStore.getValue("feature_cross_signing")) {
             encryption = canEncryptToAllUsers(client, [userId]);
         }
         roomId = await createRoom({encryption, dmUserId: userId, spinner: false, andView: false});
diff --git a/src/settings/Settings.js b/src/settings/Settings.js
index 0d72017878..b539591efd 100644
--- a/src/settings/Settings.js
+++ b/src/settings/Settings.js
@@ -152,10 +152,10 @@ export const SETTINGS = {
         default: null,
     },
     "feature_cross_signing": {
-        isFeature: true,
+        //isFeature: true,
         displayName: _td("Enable cross-signing to verify per-user instead of per-session (in development)"),
         supportedLevels: LEVELS_FEATURE,
-        default: false,
+        default: true,
     },
     "feature_event_indexing": {
         isFeature: true,
diff --git a/src/verification.js b/src/verification.js
index e00e5e05fa..ca839940e5 100644
--- a/src/verification.js
+++ b/src/verification.js
@@ -27,7 +27,7 @@ import {verificationMethods} from 'matrix-js-sdk/src/crypto';
 
 async function enable4SIfNeeded() {
     const cli = MatrixClientPeg.get();
-    if (!cli.isCryptoEnabled() || !SettingsStore.isFeatureEnabled("feature_cross_signing")) {
+    if (!cli.isCryptoEnabled() || !SettingsStore.getValue("feature_cross_signing")) {
         return false;
     }
     const usk = cli.getCrossSigningId("user_signing");