From bf1e9b09891c21d17757f6cc95ada74d6ca1f3fd Mon Sep 17 00:00:00 2001
From: Firstyear <william@blackhats.net.au>
Date: Fri, 21 Mar 2025 12:13:54 +1000
Subject: [PATCH] Make schema indexing a boolean instead of index types (#3517)

Previously on schema definitions for attributes, the list of index
types was manually set on attributes. The issue with this approach is
that not all index types apply to all attribute syntaxes. This made it
error prone not just to Kanidm developers, but to future users who
want to define custom attributes and may incorrectly index those
attributes.

Instead, this changes the index value to be a boolean to indicate
if this attribute should or should not be indexed. Internally Kanidm
has a list of appropriate indexes to apply to these syntax types.

As part of this change, the tests were reviewed to find missing index
types for syntaxes, and other causes of unindexed searches which led
to some changes around the dyngroup plugin (which pushes the boundaries
of a lot of things in Kani due to how it works).
---
 proto/src/attribute.rs                       |   3 +
 proto/src/constants.rs                       |   1 +
 server/lib/src/be/mod.rs                     |  15 +-
 server/lib/src/constants/uuids.rs            |   5 +-
 server/lib/src/entry.rs                      | 199 +++---
 server/lib/src/filter.rs                     |   5 +-
 server/lib/src/lib.rs                        |   4 +-
 server/lib/src/macros.rs                     |  16 -
 server/lib/src/migration_data/dl10/mod.rs    |   1 -
 server/lib/src/migration_data/dl10/schema.rs | 484 +------------
 server/lib/src/migration_data/dl8/schema.rs  |  61 --
 server/lib/src/migration_data/dl9/schema.rs  |  61 --
 server/lib/src/plugins/dyngroup.rs           |  20 +-
 server/lib/src/repl/consumer.rs              |  25 +-
 server/lib/src/schema.rs                     | 695 ++++++++-----------
 server/lib/src/server/mod.rs                 |  75 +-
 server/lib/src/value.rs                      |  59 ++
 17 files changed, 577 insertions(+), 1152 deletions(-)

diff --git a/proto/src/attribute.rs b/proto/src/attribute.rs
index fbd97eeb7..d26600aa4 100644
--- a/proto/src/attribute.rs
+++ b/proto/src/attribute.rs
@@ -80,6 +80,7 @@ pub enum Attribute {
     IdVerificationEcKey,
     Image,
     Index,
+    Indexed,
     IpaNtHash,
     IpaSshPubKey,
     JwsEs256PrivateKey,
@@ -311,6 +312,7 @@ impl Attribute {
             Attribute::IdVerificationEcKey => ATTR_ID_VERIFICATION_ECKEY,
             Attribute::Image => ATTR_IMAGE,
             Attribute::Index => ATTR_INDEX,
+            Attribute::Indexed => ATTR_INDEXED,
             Attribute::IpaNtHash => ATTR_IPANTHASH,
             Attribute::IpaSshPubKey => ATTR_IPASSHPUBKEY,
             Attribute::JwsEs256PrivateKey => ATTR_JWS_ES256_PRIVATE_KEY,
@@ -495,6 +497,7 @@ impl Attribute {
             ATTR_ID_VERIFICATION_ECKEY => Attribute::IdVerificationEcKey,
             ATTR_IMAGE => Attribute::Image,
             ATTR_INDEX => Attribute::Index,
+            ATTR_INDEXED => Attribute::Indexed,
             ATTR_IPANTHASH => Attribute::IpaNtHash,
             ATTR_IPASSHPUBKEY => Attribute::IpaSshPubKey,
             ATTR_JWS_ES256_PRIVATE_KEY => Attribute::JwsEs256PrivateKey,
diff --git a/proto/src/constants.rs b/proto/src/constants.rs
index 03d58a36e..7be28d9ac 100644
--- a/proto/src/constants.rs
+++ b/proto/src/constants.rs
@@ -124,6 +124,7 @@ pub const ATTR_GROUP: &str = "group";
 pub const ATTR_ID_VERIFICATION_ECKEY: &str = "id_verification_eckey";
 pub const ATTR_IMAGE: &str = "image";
 pub const ATTR_INDEX: &str = "index";
+pub const ATTR_INDEXED: &str = "indexed";
 pub const ATTR_IPANTHASH: &str = "ipanthash";
 pub const ATTR_IPASSHPUBKEY: &str = "ipasshpubkey";
 pub const ATTR_JWS_ES256_PRIVATE_KEY: &str = "jws_es256_private_key";
diff --git a/server/lib/src/be/mod.rs b/server/lib/src/be/mod.rs
index 954f8a9a5..757bfe7ba 100644
--- a/server/lib/src/be/mod.rs
+++ b/server/lib/src/be/mod.rs
@@ -549,10 +549,11 @@ pub trait BackendTransaction {
                         }
                         (_, fp) => {
                             plan.push(fp);
-                            filter_error!(
+                            let setplan = FilterPlan::InclusionInvalid(plan);
+                            error!(
+                                ?setplan,
                                 "Inclusion is unable to proceed - all terms must be fully indexed!"
                             );
-                            let setplan = FilterPlan::InclusionInvalid(plan);
                             return Ok((IdList::Partial(IDLBitRange::new()), setplan));
                         }
                     }
@@ -1427,20 +1428,16 @@ impl<'a> BackendWriteTransaction<'a> {
         if self.is_idx_slopeyness_generated()? {
             trace!("Indexing slopes available");
         } else {
-            admin_warn!(
-                "No indexing slopes available. You should consider reindexing to generate these"
-            );
+            warn!("No indexing slopes available. You should consider reindexing to generate these");
         };
 
         // Setup idxkeys here. By default we set these all to "max slope" aka
         // all indexes are "equal" but also worse case unless analysed. If they
         // have been analysed, we can set the slope factor into here.
-        let idxkeys: Result<Map<_, _>, _> = idxkeys
+        let mut idxkeys = idxkeys
             .into_iter()
             .map(|k| self.get_idx_slope(&k).map(|slope| (k, slope)))
-            .collect();
-
-        let mut idxkeys = idxkeys?;
+            .collect::<Result<Map<_, _>, _>>()?;
 
         std::mem::swap(&mut self.idxmeta_wr.deref_mut().idxkeys, &mut idxkeys);
         Ok(())
diff --git a/server/lib/src/constants/uuids.rs b/server/lib/src/constants/uuids.rs
index 06cc678a4..021364b4a 100644
--- a/server/lib/src/constants/uuids.rs
+++ b/server/lib/src/constants/uuids.rs
@@ -136,8 +136,6 @@ pub const UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL: Uuid = uuid!("00000000-0000-0000-
 pub const UUID_SCHEMA_CLASS_PERSON: Uuid = uuid!("00000000-0000-0000-0000-ffff00000044");
 pub const UUID_SCHEMA_CLASS_GROUP: Uuid = uuid!("00000000-0000-0000-0000-ffff00000045");
 pub const UUID_SCHEMA_CLASS_ACCOUNT: Uuid = uuid!("00000000-0000-0000-0000-ffff00000046");
-pub const UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: Uuid =
-    uuid!("00000000-0000-0000-0000-ffff00000187");
 pub const UUID_SCHEMA_ATTR_ATTRIBUTENAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000048");
 pub const UUID_SCHEMA_ATTR_CLASSNAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000049");
 pub const UUID_SCHEMA_ATTR_LEGALNAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000050");
@@ -329,6 +327,9 @@ pub const UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK: Uuid =
     uuid!("00000000-0000-0000-0000-ffff00000185");
 pub const UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS: Uuid =
     uuid!("00000000-0000-0000-0000-ffff00000186");
+pub const UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: Uuid =
+    uuid!("00000000-0000-0000-0000-ffff00000187");
+pub const UUID_SCHEMA_ATTR_INDEXED: Uuid = uuid!("00000000-0000-0000-0000-ffff00000188");
 
 // System and domain infos
 // I'd like to strongly criticise william of the past for making poor choices about these allocations.
diff --git a/server/lib/src/entry.rs b/server/lib/src/entry.rs
index 88efd32b8..aac8a519a 100644
--- a/server/lib/src/entry.rs
+++ b/server/lib/src/entry.rs
@@ -492,6 +492,97 @@ impl Entry<EntryInit, EntryNew> {
     }
 }
 
+impl From<SchemaAttribute> for EntryInitNew {
+    fn from(value: SchemaAttribute) -> Self {
+        EntryInitNew::from(&value)
+    }
+}
+
+impl From<&SchemaAttribute> for EntryInitNew {
+    fn from(s: &SchemaAttribute) -> Self {
+        // Build the Map of the attributes
+        let mut attrs = Eattrs::new();
+        attrs.insert(Attribute::AttributeName, vs_iutf8![s.name.as_str()]);
+        attrs.insert(Attribute::Description, vs_utf8![s.description.to_owned()]);
+        attrs.insert(Attribute::Uuid, vs_uuid![s.uuid]);
+        attrs.insert(Attribute::MultiValue, vs_bool![s.multivalue]);
+        attrs.insert(Attribute::Phantom, vs_bool![s.phantom]);
+        attrs.insert(Attribute::SyncAllowed, vs_bool![s.sync_allowed]);
+        attrs.insert(Attribute::Replicated, vs_bool![s.replicated.into()]);
+        attrs.insert(Attribute::Unique, vs_bool![s.unique]);
+        attrs.insert(Attribute::Indexed, vs_bool![s.indexed]);
+        attrs.insert(Attribute::Syntax, vs_syntax![s.syntax]);
+        attrs.insert(
+            Attribute::Class,
+            vs_iutf8![
+                EntryClass::Object.into(),
+                EntryClass::System.into(),
+                EntryClass::AttributeType.into()
+            ],
+        );
+
+        // Insert stuff.
+
+        Entry {
+            valid: EntryInit,
+            state: EntryNew,
+            attrs,
+        }
+    }
+}
+
+impl From<SchemaClass> for EntryInitNew {
+    fn from(value: SchemaClass) -> Self {
+        EntryInitNew::from(&value)
+    }
+}
+
+impl From<&SchemaClass> for EntryInitNew {
+    fn from(s: &SchemaClass) -> Self {
+        let mut attrs = Eattrs::new();
+        attrs.insert(Attribute::ClassName, vs_iutf8![s.name.as_str()]);
+        attrs.insert(Attribute::Description, vs_utf8![s.description.to_owned()]);
+        attrs.insert(Attribute::SyncAllowed, vs_bool![s.sync_allowed]);
+        attrs.insert(Attribute::Uuid, vs_uuid![s.uuid]);
+        attrs.insert(
+            Attribute::Class,
+            vs_iutf8![
+                EntryClass::Object.into(),
+                EntryClass::System.into(),
+                EntryClass::ClassType.into()
+            ],
+        );
+
+        let vs_systemmay = ValueSetIutf8::from_iter(s.systemmay.iter().map(|sm| sm.as_str()));
+        if let Some(vs) = vs_systemmay {
+            attrs.insert(Attribute::SystemMay, vs);
+        }
+
+        let vs_systemmust = ValueSetIutf8::from_iter(s.systemmust.iter().map(|sm| sm.as_str()));
+        if let Some(vs) = vs_systemmust {
+            attrs.insert(Attribute::SystemMust, vs);
+        }
+
+        let vs_systemexcludes =
+            ValueSetIutf8::from_iter(s.systemexcludes.iter().map(|sm| sm.as_str()));
+        if let Some(vs) = vs_systemexcludes {
+            attrs.insert(Attribute::SystemExcludes, vs);
+        }
+
+        let vs_systemsupplements =
+            ValueSetIutf8::from_iter(s.systemsupplements.iter().map(|sm| sm.as_str()));
+        if let Some(vs) = vs_systemsupplements {
+            attrs.insert(Attribute::SystemSupplements, vs);
+        }
+
+        Entry {
+            valid: EntryInit,
+            state: EntryNew,
+            attrs,
+        }
+    }
+}
+
 impl Entry<EntryRefresh, EntryNew> {
     pub fn from_repl_entry_v1(repl_entry: ReplEntryV1) -> Result<Self, OperationError> {
         // From the entry, we have to rebuild the ecstate and the attrs.
@@ -1949,7 +2040,7 @@ impl<STATE> Entry<EntryValid, STATE> {
         };
 
         if !valid_supplements {
-            admin_warn!(
+            warn!(
                 "Validation error, the following possible supplement classes are missing - {:?}",
                 supplements_classes
             );
@@ -2633,21 +2724,6 @@ impl<VALID, STATE> Entry<VALID, STATE> {
     // These are special types to allow returning typed values from
     // an entry, if we "know" what we expect to receive.
 
-    /// This returns an array of IndexTypes, when the type is an Optional
-    /// multivalue in schema - IE this will *not* fail if the attribute is
-    /// empty, yielding and empty array instead.
-    ///
-    /// However, the conversion to IndexType is fallible, so in case of a failure
-    /// to convert, an empty vec is returned
-    pub(crate) fn get_ava_opt_index<A: AsRef<Attribute>>(&self, attr: A) -> Option<Vec<IndexType>> {
-        if let Some(vs) = self.get_ava_set(attr) {
-            vs.as_indextype_iter().map(|i| i.collect())
-        } else {
-            // Empty, but consider as valid.
-            Some(vec![])
-        }
-    }
-
     /// Return a single value of this attributes name, or `None` if it is NOT present, or
     /// there are multiple values present (ambiguous).
     pub fn get_ava_single<A: AsRef<Attribute>>(&self, attr: A) -> Option<Value> {
@@ -3260,97 +3336,6 @@ impl<VALID, STATE> PartialEq for Entry<VALID, STATE> {
     }
 }
 
-impl From<&SchemaAttribute> for Entry<EntryInit, EntryNew> {
-    fn from(s: &SchemaAttribute) -> Self {
-        // Convert an Attribute to an entry ... make it good!
-        let uuid_v = vs_uuid![s.uuid];
-        let name_v = vs_iutf8![s.name.as_str()];
-        let desc_v = vs_utf8![s.description.to_owned()];
-
-        let multivalue_v = vs_bool![s.multivalue];
-        let sync_allowed_v = vs_bool![s.sync_allowed];
-        let replicated_v = vs_bool![s.replicated];
-        let phantom_v = vs_bool![s.phantom];
-        let unique_v = vs_bool![s.unique];
-
-        let index_v = ValueSetIndex::from_iter(s.index.iter().copied());
-
-        let syntax_v = vs_syntax![s.syntax];
-
-        // Build the Map of the attributes relevant
-        // let mut attrs: Map<AttrString, Set<Value>> = Map::with_capacity(8);
-        let mut attrs: Map<Attribute, ValueSet> = Map::new();
-        attrs.insert(Attribute::AttributeName, name_v);
-        attrs.insert(Attribute::Description, desc_v);
-        attrs.insert(Attribute::Uuid, uuid_v);
-        attrs.insert(Attribute::MultiValue, multivalue_v);
-        attrs.insert(Attribute::Phantom, phantom_v);
-        attrs.insert(Attribute::SyncAllowed, sync_allowed_v);
-        attrs.insert(Attribute::Replicated, replicated_v);
-        attrs.insert(Attribute::Unique, unique_v);
-        if let Some(vs) = index_v {
-            attrs.insert(Attribute::Index, vs);
-        }
-        attrs.insert(Attribute::Syntax, syntax_v);
-        attrs.insert(
-            Attribute::Class,
-            vs_iutf8![
-                EntryClass::Object.into(),
-                EntryClass::System.into(),
-                EntryClass::AttributeType.into()
-            ],
-        );
-
-        // Insert stuff.
-
-        Entry {
-            valid: EntryInit,
-            state: EntryNew,
-            attrs,
-        }
-    }
-}
-
-impl From<&SchemaClass> for Entry<EntryInit, EntryNew> {
-    fn from(s: &SchemaClass) -> Self {
-        let uuid_v = vs_uuid![s.uuid];
-        let name_v = vs_iutf8![s.name.as_str()];
-        let desc_v = vs_utf8![s.description.to_owned()];
-        let sync_allowed_v = vs_bool![s.sync_allowed];
-
-        let mut attrs: Map<Attribute, ValueSet> = Map::new();
-        attrs.insert(Attribute::ClassName, name_v);
-        attrs.insert(Attribute::Description, desc_v);
-        attrs.insert(Attribute::SyncAllowed, sync_allowed_v);
-        attrs.insert(Attribute::Uuid, uuid_v);
-        attrs.insert(
-            Attribute::Class,
-            vs_iutf8![
-                EntryClass::Object.into(),
-                EntryClass::System.into(),
-                EntryClass::ClassType.into()
-            ],
-        );
-
-        let vs_systemmay = ValueSetIutf8::from_iter(s.systemmay.iter().map(|sm| sm.as_str()));
-        if let Some(vs) = vs_systemmay {
-            attrs.insert(Attribute::SystemMay, vs);
-        }
-
-        let vs_systemmust = ValueSetIutf8::from_iter(s.systemmust.iter().map(|sm| sm.as_str()));
-
-        if let Some(vs) = vs_systemmust {
-            attrs.insert(Attribute::SystemMust, vs);
-        }
-
-        Entry {
-            valid: EntryInit,
-            state: EntryNew,
-            attrs,
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use crate::prelude::*;
diff --git a/server/lib/src/filter.rs b/server/lib/src/filter.rs
index 3f408f099..23ca58d4f 100644
--- a/server/lib/src/filter.rs
+++ b/server/lib/src/filter.rs
@@ -527,7 +527,8 @@ impl Filter<FilterValid> {
         // cases! The exception is *large* filters, especially from the memberof plugin. We
         // want to skip these because they can really jam up the server.
 
-        let cacheable = FilterResolved::resolve_cacheable(&self.state.inner);
+        // Don't cache anything unless we have valid indexing metadata.
+        let cacheable = idxmeta.is_some() && FilterResolved::resolve_cacheable(&self.state.inner);
 
         let cache_key = if cacheable {
             // do we have a cache?
@@ -536,6 +537,7 @@ impl Filter<FilterValid> {
                 let cache_key = (ev.get_event_origin_id(), Arc::new(self.clone()));
                 if let Some(f) = rcache.get(&cache_key) {
                     // Got it? Shortcut and return!
+                    trace!("shortcut: a resolved filter already exists.");
                     return Ok(f.as_ref().clone());
                 };
                 // Not in cache? Set the cache_key.
@@ -574,6 +576,7 @@ impl Filter<FilterValid> {
         // if cacheable == false.
         if let Some(cache_key) = cache_key {
             if let Some(rcache) = rsv_cache.as_mut() {
+                trace!(?resolved_filt, "inserting filter to resolved cache");
                 rcache.insert(cache_key, Arc::new(resolved_filt.clone()));
             }
         }
diff --git a/server/lib/src/lib.rs b/server/lib/src/lib.rs
index 870b19b0b..de196ba06 100644
--- a/server/lib/src/lib.rs
+++ b/server/lib/src/lib.rs
@@ -124,8 +124,8 @@ pub mod prelude {
     pub use kanidmd_lib_macros::*;
 
     pub(crate) use crate::valueset::{
-        ValueSet, ValueSetBool, ValueSetCid, ValueSetIndex, ValueSetIutf8, ValueSetRefer,
-        ValueSetSyntax, ValueSetT, ValueSetUtf8, ValueSetUuid,
+        ValueSet, ValueSetBool, ValueSetCid, ValueSetIutf8, ValueSetRefer, ValueSetSyntax,
+        ValueSetT, ValueSetUtf8, ValueSetUuid,
     };
 
     pub(crate) use kanidm_proto::scim_v1::{
diff --git a/server/lib/src/macros.rs b/server/lib/src/macros.rs
index f942eae4d..ef0593970 100644
--- a/server/lib/src/macros.rs
+++ b/server/lib/src/macros.rs
@@ -620,22 +620,6 @@ macro_rules! vs_syntax {
     });
 }
 
-#[allow(unused_macros)]
-#[macro_export]
-macro_rules! vs_index {
-    () => (
-        compile_error!("ValueSetIndex needs at least 1 element")
-    );
-    ($e:expr) => ({
-        ValueSetIndex::new($e)
-    });
-    ($e:expr, $($item:expr),*) => ({
-        let mut x = ValueSetIndex::new($e);
-        $(assert!(x.push($item));)*
-        x
-    });
-}
-
 #[allow(unused_macros)]
 #[macro_export]
 macro_rules! vs_cid {
diff --git a/server/lib/src/migration_data/dl10/mod.rs b/server/lib/src/migration_data/dl10/mod.rs
index b4b961824..8eac91720 100644
--- a/server/lib/src/migration_data/dl10/mod.rs
+++ b/server/lib/src/migration_data/dl10/mod.rs
@@ -69,7 +69,6 @@ pub fn phase_1_schema_attrs() -> Vec<EntryInitNew> {
         SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(),
         SCHEMA_ATTR_UNIX_PASSWORD.clone().into(),
         SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(),
-        SCHEMA_ATTR_DENIED_NAME.clone().into(),
         SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(),
         SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(),
         // DL4
diff --git a/server/lib/src/migration_data/dl10/schema.rs b/server/lib/src/migration_data/dl10/schema.rs
index 0cfc290cb..5117f7121 100644
--- a/server/lib/src/migration_data/dl10/schema.rs
+++ b/server/lib/src/migration_data/dl10/schema.rs
@@ -2,52 +2,25 @@
 use crate::constants::entries::{Attribute, EntryClass};
 use crate::constants::uuids::*;
 use crate::schema::{SchemaAttribute, SchemaClass};
-use crate::value::IndexType;
 use crate::value::SyntaxType;
 
 lazy_static!(
 
-pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
-    uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
-    name: Attribute::DisplayName,
-    description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
-    sync_allowed: true,
-    syntax: SyntaxType::Utf8String,
-    ..Default::default()
-};
-
 pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
     name: Attribute::DisplayName,
     description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
+    indexed: true,
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
 };
 
-pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
-    uuid: UUID_SCHEMA_ATTR_MAIL,
-    name: Attribute::Mail,
-    description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality],
-    unique: true,
-    multivalue: true,
-    sync_allowed: true,
-    syntax: SyntaxType::EmailAddress,
-    ..Default::default()
-};
-
 pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_MAIL,
     name: Attribute::Mail,
     description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
+    indexed: true,
     unique: true,
     multivalue: true,
     sync_allowed: true,
@@ -59,8 +32,7 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
     name: Attribute::IdVerificationEcKey,
     description: "Account verification private key".to_string(),
-
-    index: vec![IndexType::Presence],
+    indexed: true,
     unique: false,
     sync_allowed: false,
     syntax: SyntaxType::EcKeyPrivate,
@@ -82,30 +54,17 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
     name: Attribute::PrimaryCredential,
     description: "Primary credential material of the account for authentication interactively".to_string(),
-
-    index: vec![IndexType::Presence],
+    indexed: true,
     sync_allowed: true,
     syntax: SyntaxType::Credential,
     ..Default::default()
 };
 
-pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
-    uuid: UUID_SCHEMA_ATTR_LEGALNAME,
-    name: Attribute::LegalName,
-    description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
-    sync_allowed: true,
-    syntax: SyntaxType::Utf8String,
-    ..Default::default()
-};
-
 pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LEGALNAME,
     name: Attribute::LegalName,
     description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
+    indexed: true,
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -115,8 +74,7 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
     name: Attribute::NameHistory,
     description: "The history of names that a person has had".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AuditLogString,
@@ -127,7 +85,6 @@ pub static ref SCHEMA_ATTR_RADIUS_SECRET: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_RADIUS_SECRET,
     name: Attribute::RadiusSecret,
     description: "The accounts generated radius secret for device network authentication".to_string(),
-
     sync_allowed: true,
     syntax: SyntaxType::SecretUtf8String,
     ..Default::default()
@@ -137,8 +94,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
     name: Attribute::DomainName,
     description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::Presence],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
@@ -148,7 +104,6 @@ pub static ref SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND,
     name: Attribute::LdapAllowUnixPwBind,
     description: "Configuration to enable binds to LDAP objects using their UNIX password".to_string(),
-
     unique: false,
     syntax: SyntaxType::Boolean,
     ..Default::default()
@@ -158,7 +113,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_LDAP_BASEDN: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_DOMAIN_LDAP_BASEDN,
     name: Attribute::DomainLdapBasedn,
     description: "The domain's optional ldap basedn. If unset defaults to domain components of domain name".to_string(),
-
     unique: true,
     syntax: SyntaxType::Utf8StringInsensitive,
     ..Default::default()
@@ -168,7 +122,6 @@ pub static ref SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: SchemaAttribute =
     uuid: UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES,
     name: Attribute::LdapMaxQueryableAttrs,
     description: "The maximum number of LDAP attributes that can be queried in one operation".to_string(),
-
     multivalue: false,
     sync_allowed: true,
     syntax: SyntaxType::Uint32,
@@ -179,8 +132,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
     name: Attribute::DomainDisplayName,
     description: "The user-facing display name of the Kanidm domain".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
 };
@@ -189,8 +141,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
     name: Attribute::DomainUuid,
     description: "The domain's uuid, used in CSN and trust relationships".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::Uuid,
     ..Default::default()
@@ -200,27 +151,16 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
     name: Attribute::DomainSsid,
     description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
 };
 
-pub static ref SCHEMA_ATTR_DENIED_NAME: SchemaAttribute = SchemaAttribute {
-    uuid: UUID_SCHEMA_ATTR_DENIED_NAME,
-    name: Attribute::DeniedName,
-    description: "Iname values that are not allowed to be used in 'name'.".to_string(),
-
-    syntax: SyntaxType::Utf8StringIname,
-    ..Default::default()
-};
-
 pub static ref SCHEMA_ATTR_DENIED_NAME_DL10: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DENIED_NAME,
     name: Attribute::DeniedName,
     description: "Iname values that are not allowed to be used in 'name'.".to_string(),
-
     syntax: SyntaxType::Utf8StringIname,
     multivalue: true,
     ..Default::default()
@@ -230,7 +170,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_TOKEN_KEY: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_TOKEN_KEY,
     name: Attribute::DomainTokenKey,
     description: "The domain token encryption private key (NOT USED)".to_string(),
-
     syntax: SyntaxType::SecretUtf8String,
     ..Default::default()
 };
@@ -248,8 +187,7 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
     name: Attribute::GidNumber,
     description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::Uint32,
@@ -260,7 +198,6 @@ pub static ref SCHEMA_ATTR_BADLIST_PASSWORD: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_BADLIST_PASSWORD,
     name: Attribute::BadlistPassword,
     description: "A password that is badlisted meaning that it can not be set as a valid password by any user account".to_string(),
-
     multivalue: true,
     syntax: SyntaxType::Utf8StringInsensitive,
     ..Default::default()
@@ -270,7 +207,6 @@ pub static ref SCHEMA_ATTR_AUTH_SESSION_EXPIRY: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_AUTH_SESSION_EXPIRY,
     name: Attribute::AuthSessionExpiry,
     description: "An expiration time for an authentication session".to_string(),
-
     syntax: SyntaxType::Uint32,
     ..Default::default()
 };
@@ -279,7 +215,6 @@ pub static ref SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY,
     name: Attribute::PrivilegeExpiry,
     description: "An expiration time for a privileged authentication session".to_string(),
-
     syntax: SyntaxType::Uint32,
     ..Default::default()
 };
@@ -288,7 +223,6 @@ pub static ref SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH: SchemaAttribute = Schem
     uuid: UUID_SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH,
     name: Attribute::AuthPasswordMinimumLength,
     description: "Minimum length of passwords".to_string(),
-
     syntax: SyntaxType::Uint32,
     ..Default::default()
 };
@@ -297,7 +231,6 @@ pub static ref SCHEMA_ATTR_LOGINSHELL: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LOGINSHELL,
     name: Attribute::LoginShell,
     description: "A POSIX user's UNIX login shell".to_string(),
-
     sync_allowed: true,
     syntax: SyntaxType::Utf8StringInsensitive,
     ..Default::default()
@@ -307,8 +240,7 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
     name: Attribute::UnixPassword,
     description: "A POSIX user's UNIX login password".to_string(),
-
-    index: vec![IndexType::Presence],
+    indexed: true,
     syntax: SyntaxType::Credential,
     ..Default::default()
 };
@@ -317,8 +249,7 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
     name: Attribute::NsUniqueId,
     description: "A unique id compatibility for 389-ds/dsee".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::NsUniqueId,
@@ -329,7 +260,6 @@ pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_ACCOUNT_EXPIRE,
     name: Attribute::AccountExpire,
     description: "The datetime after which this account no longer may authenticate".to_string(),
-
     sync_allowed: true,
     syntax: SyntaxType::DateTime,
     ..Default::default()
@@ -339,7 +269,6 @@ pub static ref SCHEMA_ATTR_ACCOUNT_VALID_FROM: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_ACCOUNT_VALID_FROM,
     name: Attribute::AccountValidFrom,
     description: "The datetime after which this account may commence authenticating".to_string(),
-
     sync_allowed: true,
     syntax: SyntaxType::DateTime,
     ..Default::default()
@@ -349,7 +278,6 @@ pub static ref SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: SchemaAttribute = Schem
     uuid: UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST,
     name: Attribute::WebauthnAttestationCaList,
     description: "A set of CA's that limit devices that can be used with webauthn".to_string(),
-
     syntax: SyntaxType::WebauthnAttestationCaList,
     multivalue: true,
     ..Default::default()
@@ -359,27 +287,16 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
     name: Attribute::OAuth2RsName,
     description: "The unique name of an external Oauth2 resource".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
 };
 
-pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN: SchemaAttribute = SchemaAttribute {
-    uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN,
-    name: Attribute::OAuth2RsOrigin,
-    description: "The origin domain of an oauth2 resource server".to_string(),
-
-    syntax: SyntaxType::Url,
-    ..Default::default()
-};
-
 pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN,
     name: Attribute::OAuth2RsOrigin,
     description: "The origin domain of an OAuth2 client".to_string(),
-
     syntax: SyntaxType::Url,
     multivalue: true,
     ..Default::default()
@@ -389,7 +306,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING: SchemaAttribute = SchemaAtt
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING,
     name: Attribute::OAuth2RsOriginLanding,
     description: "The landing page of an RS, that will automatically trigger the auth process".to_string(),
-
     syntax: SyntaxType::Url,
     ..Default::default()
 };
@@ -399,7 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4: SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT,
     name: Attribute::OAuth2AllowLocalhostRedirect,
     description: "Allow public clients associated to this RS to redirect to localhost".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -408,8 +323,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
     name: Attribute::OAuth2RsClaimMap,
     description: "A set of custom claims mapped to group memberships of accounts".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     // CHANGE ME
     syntax: SyntaxType::OauthClaimMap,
@@ -420,8 +334,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
     name: Attribute::OAuth2RsScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -431,8 +344,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
     name: Attribute::OAuth2RsSupScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -442,7 +354,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET: SchemaAttribute = SchemaAttri
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET,
     name: Attribute::OAuth2RsBasicSecret,
     description: "When using oauth2 basic authentication, the secret string of the resource server".to_string(),
-
     syntax: SyntaxType::SecretUtf8String,
     ..Default::default()
 };
@@ -451,7 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY,
     name: Attribute::OAuth2RsTokenKey,
     description: "An oauth2 resource servers unique token signing key".to_string(),
-
     syntax: SyntaxType::SecretUtf8String,
     ..Default::default()
 };
@@ -460,7 +370,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES: SchemaAttribute = SchemaAt
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES,
     name: Attribute::OAuth2RsImplicitScopes,
     description: "An oauth2 resource servers scopes that are implicitly granted to all users".to_string(),
-
     multivalue: true,
     syntax: SyntaxType::OauthScope,
     ..Default::default()
@@ -470,8 +379,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
     uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
     name: Attribute::OAuth2ConsentScopeMap,
     description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -481,7 +389,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7: SchemaAttribute = Sch
     uuid: UUID_SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI,
     name: Attribute::OAuth2StrictRedirectUri,
     description: "Represents if strict redirect uri enforcement is enabled.".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -491,7 +398,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9: SchemaAttribute = Sche
     uuid: UUID_SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE,
     name: Attribute::OAuth2DeviceFlowEnable,
     description: "Represents if OAuth2 Device Flow is permitted on this client.".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -500,7 +406,6 @@ pub static ref SCHEMA_ATTR_ES256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_ES256_PRIVATE_KEY_DER,
     name: Attribute::Es256PrivateKeyDer,
     description: "An es256 private key".to_string(),
-
     syntax: SyntaxType::PrivateBinary,
     ..Default::default()
 };
@@ -509,7 +414,6 @@ pub static ref SCHEMA_ATTR_RS256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER,
     name: Attribute::Rs256PrivateKeyDer,
     description: "An rs256 private key".to_string(),
-
     syntax: SyntaxType::PrivateBinary,
     ..Default::default()
 };
@@ -518,8 +422,7 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
     name: Attribute::JwsEs256PrivateKey,
     description: "An es256 private key for jws".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::JwsKeyEs256,
     ..Default::default()
@@ -530,7 +433,6 @@ pub static ref SCHEMA_ATTR_PRIVATE_COOKIE_KEY: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_PRIVATE_COOKIE_KEY,
     name: Attribute::PrivateCookieKey,
     description: "An private cookie hmac key".to_string(),
-
     syntax: SyntaxType::PrivateBinary,
     ..Default::default()
 };
@@ -539,7 +441,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE: SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE,
     name: Attribute::OAuth2AllowInsecureClientDisablePkce,
     description: "Allows disabling of PKCE for insecure OAuth2 clients".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -548,7 +449,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE: SchemaAttribute = Sc
     uuid: UUID_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE,
     name: Attribute::OAuth2JwtLegacyCryptoEnable,
     description: "Allows enabling legacy JWT cryptograhpy for clients".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -557,8 +457,7 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
     uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
     name: Attribute::CredentialUpdateIntentToken,
     description: "The status of a credential update intent token".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::IntentToken,
     ..Default::default()
@@ -568,8 +467,7 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_PASSKEYS,
     name: Attribute::PassKeys,
     description: "A set of registered passkeys".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::Passkey,
@@ -580,8 +478,7 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
     name: Attribute::AttestedPasskeys,
     description: "A set of registered device keys".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AttestedPasskey,
@@ -592,7 +489,6 @@ pub static ref SCHEMA_ATTR_DYNGROUP_FILTER: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DYNGROUP_FILTER,
     name: Attribute::DynGroupFilter,
     description: "A filter describing the set of entries to add to a dynamic group".to_string(),
-
     syntax: SyntaxType::JsonFilter,
     ..Default::default()
 };
@@ -601,7 +497,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME: SchemaAttribute = Schem
     uuid: UUID_SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME,
     name: Attribute::OAuth2PreferShortUsername,
     description: "Use 'name' instead of 'spn' in the preferred_username claim".to_string(),
-
     syntax: SyntaxType::Boolean,
     ..Default::default()
 };
@@ -610,8 +505,7 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
     name: Attribute::ApiTokenSession,
     description: "A session entry related to an issued API token".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     multivalue: true,
     syntax: SyntaxType::ApiToken,
@@ -622,8 +516,7 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
     name: Attribute::UserAuthTokenSession,
     description: "A session entry related to an issued user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     multivalue: true,
     syntax: SyntaxType::Session,
@@ -634,8 +527,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
     name: Attribute::OAuth2Session,
     description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::Oauth2Session,
     ..Default::default()
@@ -645,8 +537,7 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
     name: Attribute::SyncTokenSession,
     description: "A session entry related to an issued sync token".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     unique: true,
     syntax: SyntaxType::ApiToken,
     ..Default::default()
@@ -656,7 +547,6 @@ pub static ref SCHEMA_ATTR_SYNC_COOKIE: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_SYNC_COOKIE,
     name: Attribute::SyncCookie,
     description: "A private sync cookie for a remote IDM source".to_string(),
-
     syntax: SyntaxType::PrivateBinary,
     ..Default::default()
 };
@@ -665,8 +555,7 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
     name: Attribute::GrantUiHint,
     description: "A UI hint that is granted via membership to a group".to_string(),
-
-    index: vec![IndexType::Equality],
+    indexed: true,
     multivalue: true,
     syntax: SyntaxType::UiHint,
     ..Default::default()
@@ -676,7 +565,6 @@ pub static ref SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL: SchemaAttribute = SchemaAttri
     uuid: UUID_SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL,
     name: Attribute::SyncCredentialPortal,
     description: "The url of an external credential portal for synced accounts to visit to update their credentials".to_string(),
-
     syntax: SyntaxType::Url,
     ..Default::default()
 };
@@ -685,7 +573,6 @@ pub static ref SCHEMA_ATTR_SYNC_YIELD_AUTHORITY: SchemaAttribute = SchemaAttribu
     uuid: UUID_SCHEMA_ATTR_SYNC_YIELD_AUTHORITY,
     name: Attribute::SyncYieldAuthority,
     description: "A set of attributes that have their authority yielded to Kanidm in a sync agreement".to_string(),
-
     multivalue: true,
     syntax: SyntaxType::Utf8StringInsensitive,
     ..Default::default()
@@ -695,7 +582,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM,
     name: Attribute::CredentialTypeMinimum,
     description: "The minimum level of credential type that can satisfy this policy".to_string(),
-
     multivalue: false,
     syntax: SyntaxType::CredentialType,
     ..Default::default()
@@ -705,7 +591,6 @@ pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6: SchemaAttribute = Schem
     uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS,
     name: Attribute::LimitSearchMaxResults,
     description: "The maximum number of query results that may be returned in a single operation".to_string(),
-
     multivalue: false,
     syntax: SyntaxType::Uint32,
     ..Default::default()
@@ -715,7 +600,6 @@ pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6: SchemaAttribute = S
     uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST,
     name: Attribute::LimitSearchMaxFilterTest,
     description: "The maximum number of entries that may be examined in a partially indexed query".to_string(),
-
     multivalue: false,
     syntax: SyntaxType::Uint32,
     ..Default::default()
@@ -735,6 +619,7 @@ pub static ref SCHEMA_ATTR_KEY_PROVIDER_DL6: SchemaAttribute = SchemaAttribute {
     name: Attribute::KeyProvider,
     description: "".to_string(),
     multivalue: false,
+    indexed: true,
     syntax: SyntaxType::ReferenceUuid,
     ..Default::default()
 };
@@ -800,6 +685,7 @@ pub static ref SCHEMA_ATTR_REFERS_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_REFERS,
     name: Attribute::Refers,
     description: "A reference to linked object".to_string(),
+    indexed: true,
     multivalue: false,
     syntax: SyntaxType::ReferenceUuid,
     ..Default::default()
@@ -809,8 +695,8 @@ pub static ref SCHEMA_ATTR_LINKED_GROUP_DL8: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LINKED_GROUP,
     name: Attribute::LinkedGroup,
     description: "A reference linking a group to an entry".to_string(),
-
     multivalue: false,
+    indexed: true,
     syntax: SyntaxType::ReferenceUuid,
     ..Default::default()
 };
@@ -819,7 +705,6 @@ pub static ref SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8: SchemaAttribute = Sc
     uuid: UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK,
     name: Attribute::AllowPrimaryCredFallback,
     description: "Allow fallback to primary password if no POSIX password exists".to_string(),
-
     multivalue: false,
     syntax: SyntaxType::Boolean,
     ..Default::default()
@@ -838,57 +723,13 @@ pub static ref SCHEMA_ATTR_APPLICATION_PASSWORD_DL8: SchemaAttribute = SchemaAtt
     uuid: UUID_SCHEMA_ATTR_APPLICATION_PASSWORD,
     name: Attribute::ApplicationPassword,
     description: "A set of application passwords".to_string(),
-
     multivalue: true,
+    indexed: true,
     syntax: SyntaxType::ApplicationPassword,
     ..Default::default()
 };
 
 // === classes ===
-
-pub static ref SCHEMA_CLASS_PERSON: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_PERSON,
-    name: EntryClass::Person.into(),
-    description: "Object representation of a person".to_string(),
-
-    sync_allowed: true,
-    systemmay: vec![
-        Attribute::Mail,
-        Attribute::LegalName,
-        ],
-    systemmust: vec![
-        Attribute::DisplayName,
-        Attribute::Name,
-        Attribute::IdVerificationEcKey],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_PERSON_DL5: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_PERSON,
-    name: EntryClass::Person.into(),
-    description: "Object representation of a person".to_string(),
-
-    sync_allowed: true,
-    systemmay: vec![
-        Attribute::PrimaryCredential,
-        Attribute::PassKeys,
-        Attribute::AttestedPasskeys,
-        Attribute::CredentialUpdateIntentToken,
-        Attribute::SshPublicKey,
-        Attribute::RadiusSecret,
-        Attribute::OAuth2ConsentScopeMap,
-        Attribute::UserAuthTokenSession,
-        Attribute::OAuth2Session,
-        Attribute::Mail,
-        Attribute::LegalName,
-    ],
-    systemmust: vec![
-        Attribute::IdVerificationEcKey
-    ],
-    systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_PERSON_DL8: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_PERSON,
     name: EntryClass::Person.into(),
@@ -961,24 +802,6 @@ pub static ref SCHEMA_CLASS_DYNGROUP: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL6: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY,
-    name: EntryClass::AccountPolicy.into(),
-    description: "Policies applied to accounts that are members of a group".to_string(),
-
-    systemmay: vec![
-        Attribute::AuthSessionExpiry,
-        Attribute::PrivilegeExpiry,
-        Attribute::AuthPasswordMinimumLength,
-        Attribute::CredentialTypeMinimum,
-        Attribute::WebauthnAttestationCaList,
-        Attribute::LimitSearchMaxResults,
-        Attribute::LimitSearchMaxFilterTest,
-    ],
-    systemsupplements: vec![Attribute::Group.into()],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY,
     name: EntryClass::AccountPolicy.into(),
@@ -998,40 +821,6 @@ pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_ACCOUNT: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_ACCOUNT,
-    name: EntryClass::Account.into(),
-    description: "Object representation of an account".to_string(),
-
-    sync_allowed: true,
-    systemmay: vec![
-        Attribute::PrimaryCredential,
-        Attribute::PassKeys,
-        Attribute::AttestedPasskeys,
-        Attribute::CredentialUpdateIntentToken,
-        Attribute::SshPublicKey,
-        Attribute::RadiusSecret,
-        Attribute::AccountExpire,
-        Attribute::AccountValidFrom,
-        Attribute::Mail,
-        Attribute::OAuth2ConsentScopeMap,
-        Attribute::UserAuthTokenSession,
-        Attribute::OAuth2Session,
-        Attribute::Description,
-        Attribute::NameHistory,
-    ],
-    systemmust: vec![
-            Attribute::DisplayName,
-            Attribute::Name,
-            Attribute::Spn
-    ],
-    systemsupplements: vec![
-        EntryClass::Person.into(),
-        EntryClass::ServiceAccount.into(),
-    ],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_ACCOUNT,
     name: EntryClass::Account.into(),
@@ -1056,29 +845,6 @@ pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL6: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT,
-    name: EntryClass::ServiceAccount.into(),
-    description: "Object representation of service account".to_string(),
-
-    sync_allowed: true,
-    systemmay: vec![
-        Attribute::SshPublicKey,
-        Attribute::UserAuthTokenSession,
-        Attribute::OAuth2Session,
-        Attribute::OAuth2ConsentScopeMap,
-        Attribute::Description,
-
-        Attribute::Mail,
-        Attribute::PrimaryCredential,
-        Attribute::ApiTokenSession,
-
-        Attribute::JwsEs256PrivateKey,
-    ],
-    systemexcludes: vec![EntryClass::Person.into()],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT,
     name: EntryClass::ServiceAccount.into(),
@@ -1100,23 +866,6 @@ pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL6: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT,
-    name: EntryClass::SyncAccount.into(),
-    description: "Object representation of sync account".to_string(),
-
-    systemmust: vec![Attribute::Name],
-    systemmay: vec![
-        Attribute::SyncTokenSession,
-        Attribute::SyncCookie,
-        Attribute::SyncCredentialPortal,
-        Attribute::SyncYieldAuthority,
-        Attribute::JwsEs256PrivateKey,
-    ],
-    systemexcludes: vec![EntryClass::Account.into()],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT,
     name: EntryClass::SyncAccount.into(),
@@ -1133,100 +882,6 @@ pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL6: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
-    name: EntryClass::DomainInfo.into(),
-    description: "Local domain information and configuration".to_string(),
-
-    systemmay: vec![
-        Attribute::DomainSsid,
-        Attribute::DomainLdapBasedn,
-        Attribute::LdapAllowUnixPwBind,
-        Attribute::PrivateCookieKey,
-        Attribute::FernetPrivateKeyStr,
-        Attribute::Es256PrivateKeyDer,
-        Attribute::PatchLevel,
-        Attribute::DomainDevelopmentTaint,
-    ],
-    systemmust: vec![
-        Attribute::Name,
-        Attribute::DomainUuid,
-        Attribute::DomainName,
-        Attribute::DomainDisplayName,
-        Attribute::Version,
-    ],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL7: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
-    name: EntryClass::DomainInfo.into(),
-    description: "Local domain information and configuration".to_string(),
-
-    systemmay: vec![
-        Attribute::DomainSsid,
-        Attribute::DomainLdapBasedn,
-        Attribute::LdapAllowUnixPwBind,
-        Attribute::PatchLevel,
-        Attribute::DomainDevelopmentTaint,
-    ],
-    systemmust: vec![
-        Attribute::Name,
-        Attribute::DomainUuid,
-        Attribute::DomainName,
-        Attribute::DomainDisplayName,
-        Attribute::Version,
-    ],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL8: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
-    name: EntryClass::DomainInfo.into(),
-    description: "Local domain information and configuration".to_string(),
-
-    systemmay: vec![
-        Attribute::DomainSsid,
-        Attribute::DomainLdapBasedn,
-        Attribute::LdapAllowUnixPwBind,
-        Attribute::Image,
-        Attribute::PatchLevel,
-        Attribute::DomainDevelopmentTaint,
-    ],
-    systemmust: vec![
-        Attribute::Name,
-        Attribute::DomainUuid,
-        Attribute::DomainName,
-        Attribute::DomainDisplayName,
-        Attribute::Version,
-    ],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL9: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
-    name: EntryClass::DomainInfo.into(),
-    description: "Local domain information and configuration".to_string(),
-
-    systemmay: vec![
-        Attribute::DomainSsid,
-        Attribute::DomainLdapBasedn,
-        Attribute::LdapAllowUnixPwBind,
-        Attribute::Image,
-        Attribute::PatchLevel,
-        Attribute::DomainDevelopmentTaint,
-        Attribute::DomainAllowEasterEggs,
-    ],
-    systemmust: vec![
-        Attribute::Name,
-        Attribute::DomainUuid,
-        Attribute::DomainName,
-        Attribute::DomainDisplayName,
-        Attribute::Version,
-    ],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL10: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
     name: EntryClass::DomainInfo.into(),
@@ -1290,83 +945,6 @@ pub static ref SCHEMA_CLASS_SYSTEM_CONFIG: SchemaClass = SchemaClass {
     ..Default::default()
 };
 
-pub static ref SCHEMA_CLASS_OAUTH2_RS_DL4: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
-    name: EntryClass::OAuth2ResourceServer.into(),
-    description: "The class representing a configured Oauth2 Resource Server".to_string(),
-
-    systemmay: vec![
-        Attribute::Description,
-        Attribute::OAuth2RsScopeMap,
-        Attribute::OAuth2RsSupScopeMap,
-        Attribute::Rs256PrivateKeyDer,
-        Attribute::OAuth2JwtLegacyCryptoEnable,
-        Attribute::OAuth2PreferShortUsername,
-        Attribute::OAuth2RsOriginLanding,
-        Attribute::Image,
-        Attribute::OAuth2RsClaimMap,
-    ],
-    systemmust: vec![
-        Attribute::OAuth2RsName,
-        Attribute::DisplayName,
-        Attribute::OAuth2RsOrigin,
-        Attribute::OAuth2RsTokenKey,
-        Attribute::Es256PrivateKeyDer,
-    ],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_OAUTH2_RS_DL5: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
-    name: EntryClass::OAuth2ResourceServer.into(),
-    description: "The class representing a configured Oauth2 Resource Server".to_string(),
-
-    systemmay: vec![
-        Attribute::Description,
-        Attribute::OAuth2RsScopeMap,
-        Attribute::OAuth2RsSupScopeMap,
-        Attribute::Rs256PrivateKeyDer,
-        Attribute::OAuth2JwtLegacyCryptoEnable,
-        Attribute::OAuth2PreferShortUsername,
-        Attribute::OAuth2RsOriginLanding,
-        Attribute::Image,
-        Attribute::OAuth2RsClaimMap,
-        Attribute::OAuth2Session,
-    ],
-    systemmust: vec![
-        Attribute::OAuth2RsOrigin,
-        Attribute::OAuth2RsTokenKey,
-        Attribute::Es256PrivateKeyDer,
-    ],
-    ..Default::default()
-};
-
-pub static ref SCHEMA_CLASS_OAUTH2_RS_DL7: SchemaClass = SchemaClass {
-    uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
-    name: EntryClass::OAuth2ResourceServer.into(),
-    description: "The class representing a configured OAuth2 Client".to_string(),
-
-    systemmay: vec![
-        Attribute::Description,
-        Attribute::OAuth2RsScopeMap,
-        Attribute::OAuth2RsSupScopeMap,
-        Attribute::Rs256PrivateKeyDer,
-        Attribute::OAuth2JwtLegacyCryptoEnable,
-        Attribute::OAuth2PreferShortUsername,
-        Attribute::Image,
-        Attribute::OAuth2RsClaimMap,
-        Attribute::OAuth2Session,
-        Attribute::OAuth2RsOrigin,
-        Attribute::OAuth2StrictRedirectUri,
-    ],
-    systemmust: vec![
-        Attribute::OAuth2RsOriginLanding,
-        Attribute::OAuth2RsTokenKey,
-        Attribute::Es256PrivateKeyDer,
-    ],
-    ..Default::default()
-};
-
 pub static ref SCHEMA_CLASS_OAUTH2_RS_DL9: SchemaClass = SchemaClass {
     uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
     name: EntryClass::OAuth2ResourceServer.into(),
diff --git a/server/lib/src/migration_data/dl8/schema.rs b/server/lib/src/migration_data/dl8/schema.rs
index 1a3ebbca9..e11958096 100644
--- a/server/lib/src/migration_data/dl8/schema.rs
+++ b/server/lib/src/migration_data/dl8/schema.rs
@@ -2,7 +2,6 @@
 use crate::constants::entries::{Attribute, EntryClass};
 use crate::constants::uuids::*;
 use crate::schema::{SchemaAttribute, SchemaClass};
-use crate::value::IndexType;
 use crate::value::SyntaxType;
 
 lazy_static!(
@@ -11,8 +10,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
     name: Attribute::DisplayName,
     description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -22,8 +19,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
     name: Attribute::DisplayName,
     description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -33,8 +28,6 @@ pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_MAIL,
     name: Attribute::Mail,
     description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     sync_allowed: true,
@@ -46,8 +39,6 @@ pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_MAIL,
     name: Attribute::Mail,
     description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     unique: true,
     multivalue: true,
     sync_allowed: true,
@@ -59,8 +50,6 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
     name: Attribute::IdVerificationEcKey,
     description: "Account verification private key".to_string(),
-
-    index: vec![IndexType::Presence],
     unique: false,
     sync_allowed: false,
     syntax: SyntaxType::EcKeyPrivate,
@@ -82,8 +71,6 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
     name: Attribute::PrimaryCredential,
     description: "Primary credential material of the account for authentication interactively".to_string(),
-
-    index: vec![IndexType::Presence],
     sync_allowed: true,
     syntax: SyntaxType::Credential,
     ..Default::default()
@@ -93,8 +80,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LEGALNAME,
     name: Attribute::LegalName,
     description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -104,8 +89,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LEGALNAME,
     name: Attribute::LegalName,
     description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -115,8 +98,6 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
     name: Attribute::NameHistory,
     description: "The history of names that a person has had".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AuditLogString,
@@ -137,8 +118,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
     name: Attribute::DomainName,
     description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::Presence],
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
@@ -168,8 +147,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
     name: Attribute::DomainDisplayName,
     description: "The user-facing display name of the Kanidm domain".to_string(),
-
-    index: vec![IndexType::Equality],
     syntax: SyntaxType::Utf8String,
     ..Default::default()
 };
@@ -178,8 +155,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
     name: Attribute::DomainUuid,
     description: "The domain's uuid, used in CSN and trust relationships".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Uuid,
     ..Default::default()
@@ -189,8 +164,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
     name: Attribute::DomainSsid,
     description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -237,8 +210,6 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
     name: Attribute::GidNumber,
     description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::Uint32,
@@ -296,8 +267,6 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
     name: Attribute::UnixPassword,
     description: "A POSIX user's UNIX login password".to_string(),
-
-    index: vec![IndexType::Presence],
     syntax: SyntaxType::Credential,
     ..Default::default()
 };
@@ -306,8 +275,6 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
     name: Attribute::NsUniqueId,
     description: "A unique id compatibility for 389-ds/dsee".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::NsUniqueId,
@@ -348,8 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
     name: Attribute::OAuth2RsName,
     description: "The unique name of an external Oauth2 resource".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
@@ -397,8 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
     name: Attribute::OAuth2RsClaimMap,
     description: "A set of custom claims mapped to group memberships of accounts".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     // CHANGE ME
     syntax: SyntaxType::OauthClaimMap,
@@ -409,8 +372,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
     name: Attribute::OAuth2RsScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -420,8 +381,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
     name: Attribute::OAuth2RsSupScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -459,8 +418,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
     uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
     name: Attribute::OAuth2ConsentScopeMap,
     description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -507,8 +464,6 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
     name: Attribute::JwsEs256PrivateKey,
     description: "An es256 private key for jws".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::JwsKeyEs256,
     ..Default::default()
@@ -546,8 +501,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
     uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
     name: Attribute::CredentialUpdateIntentToken,
     description: "The status of a credential update intent token".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::IntentToken,
     ..Default::default()
@@ -557,8 +510,6 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_PASSKEYS,
     name: Attribute::PassKeys,
     description: "A set of registered passkeys".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::Passkey,
@@ -569,8 +520,6 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
     name: Attribute::AttestedPasskeys,
     description: "A set of registered device keys".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AttestedPasskey,
@@ -599,8 +548,6 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
     name: Attribute::ApiTokenSession,
     description: "A session entry related to an issued API token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     syntax: SyntaxType::ApiToken,
@@ -611,8 +558,6 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
     name: Attribute::UserAuthTokenSession,
     description: "A session entry related to an issued user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     syntax: SyntaxType::Session,
@@ -623,8 +568,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
     name: Attribute::OAuth2Session,
     description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::Oauth2Session,
     ..Default::default()
@@ -634,8 +577,6 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
     name: Attribute::SyncTokenSession,
     description: "A session entry related to an issued sync token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::ApiToken,
     ..Default::default()
@@ -654,8 +595,6 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
     name: Attribute::GrantUiHint,
     description: "A UI hint that is granted via membership to a group".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::UiHint,
     ..Default::default()
diff --git a/server/lib/src/migration_data/dl9/schema.rs b/server/lib/src/migration_data/dl9/schema.rs
index 1a3ebbca9..e11958096 100644
--- a/server/lib/src/migration_data/dl9/schema.rs
+++ b/server/lib/src/migration_data/dl9/schema.rs
@@ -2,7 +2,6 @@
 use crate::constants::entries::{Attribute, EntryClass};
 use crate::constants::uuids::*;
 use crate::schema::{SchemaAttribute, SchemaClass};
-use crate::value::IndexType;
 use crate::value::SyntaxType;
 
 lazy_static!(
@@ -11,8 +10,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
     name: Attribute::DisplayName,
     description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -22,8 +19,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
     name: Attribute::DisplayName,
     description: "The publicly visible display name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -33,8 +28,6 @@ pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_MAIL,
     name: Attribute::Mail,
     description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     sync_allowed: true,
@@ -46,8 +39,6 @@ pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_MAIL,
     name: Attribute::Mail,
     description: "Mail addresses of the object".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     unique: true,
     multivalue: true,
     sync_allowed: true,
@@ -59,8 +50,6 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
     name: Attribute::IdVerificationEcKey,
     description: "Account verification private key".to_string(),
-
-    index: vec![IndexType::Presence],
     unique: false,
     sync_allowed: false,
     syntax: SyntaxType::EcKeyPrivate,
@@ -82,8 +71,6 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
     name: Attribute::PrimaryCredential,
     description: "Primary credential material of the account for authentication interactively".to_string(),
-
-    index: vec![IndexType::Presence],
     sync_allowed: true,
     syntax: SyntaxType::Credential,
     ..Default::default()
@@ -93,8 +80,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LEGALNAME,
     name: Attribute::LegalName,
     description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -104,8 +89,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_LEGALNAME,
     name: Attribute::LegalName,
     description: "The private and sensitive legal name of this person".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::SubString],
     sync_allowed: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -115,8 +98,6 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
     name: Attribute::NameHistory,
     description: "The history of names that a person has had".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AuditLogString,
@@ -137,8 +118,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
     name: Attribute::DomainName,
     description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
-
-    index: vec![IndexType::Equality, IndexType::Presence],
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
@@ -168,8 +147,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
     name: Attribute::DomainDisplayName,
     description: "The user-facing display name of the Kanidm domain".to_string(),
-
-    index: vec![IndexType::Equality],
     syntax: SyntaxType::Utf8String,
     ..Default::default()
 };
@@ -178,8 +155,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
     name: Attribute::DomainUuid,
     description: "The domain's uuid, used in CSN and trust relationships".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Uuid,
     ..Default::default()
@@ -189,8 +164,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
     name: Attribute::DomainSsid,
     description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Utf8String,
     ..Default::default()
@@ -237,8 +210,6 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
     name: Attribute::GidNumber,
     description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::Uint32,
@@ -296,8 +267,6 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
     name: Attribute::UnixPassword,
     description: "A POSIX user's UNIX login password".to_string(),
-
-    index: vec![IndexType::Presence],
     syntax: SyntaxType::Credential,
     ..Default::default()
 };
@@ -306,8 +275,6 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
     name: Attribute::NsUniqueId,
     description: "A unique id compatibility for 389-ds/dsee".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     sync_allowed: true,
     syntax: SyntaxType::NsUniqueId,
@@ -348,8 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
     name: Attribute::OAuth2RsName,
     description: "The unique name of an external Oauth2 resource".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::Utf8StringIname,
     ..Default::default()
@@ -397,8 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
     name: Attribute::OAuth2RsClaimMap,
     description: "A set of custom claims mapped to group memberships of accounts".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     // CHANGE ME
     syntax: SyntaxType::OauthClaimMap,
@@ -409,8 +372,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
     name: Attribute::OAuth2RsScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -420,8 +381,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
     name: Attribute::OAuth2RsSupScopeMap,
     description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -459,8 +418,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
     uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
     name: Attribute::OAuth2ConsentScopeMap,
     description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::OauthScopeMap,
     ..Default::default()
@@ -507,8 +464,6 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
     uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
     name: Attribute::JwsEs256PrivateKey,
     description: "An es256 private key for jws".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::JwsKeyEs256,
     ..Default::default()
@@ -546,8 +501,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
     uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
     name: Attribute::CredentialUpdateIntentToken,
     description: "The status of a credential update intent token".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::IntentToken,
     ..Default::default()
@@ -557,8 +510,6 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_PASSKEYS,
     name: Attribute::PassKeys,
     description: "A set of registered passkeys".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::Passkey,
@@ -569,8 +520,6 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
     name: Attribute::AttestedPasskeys,
     description: "A set of registered device keys".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     sync_allowed: true,
     syntax: SyntaxType::AttestedPasskey,
@@ -599,8 +548,6 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
     name: Attribute::ApiTokenSession,
     description: "A session entry related to an issued API token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     syntax: SyntaxType::ApiToken,
@@ -611,8 +558,6 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
     uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
     name: Attribute::UserAuthTokenSession,
     description: "A session entry related to an issued user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     multivalue: true,
     syntax: SyntaxType::Session,
@@ -623,8 +568,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
     name: Attribute::OAuth2Session,
     description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::Oauth2Session,
     ..Default::default()
@@ -634,8 +577,6 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
     uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
     name: Attribute::SyncTokenSession,
     description: "A session entry related to an issued sync token".to_string(),
-
-    index: vec![IndexType::Equality],
     unique: true,
     syntax: SyntaxType::ApiToken,
     ..Default::default()
@@ -654,8 +595,6 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
     uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
     name: Attribute::GrantUiHint,
     description: "A UI hint that is granted via membership to a group".to_string(),
-
-    index: vec![IndexType::Equality],
     multivalue: true,
     syntax: SyntaxType::UiHint,
     ..Default::default()
diff --git a/server/lib/src/plugins/dyngroup.rs b/server/lib/src/plugins/dyngroup.rs
index ae7fd2337..c2d2075fd 100644
--- a/server/lib/src/plugins/dyngroup.rs
+++ b/server/lib/src/plugins/dyngroup.rs
@@ -109,7 +109,7 @@ impl DynGroup {
                 nd_group.purge_ava(Attribute::DynMember);
             }
 
-            // Insert it to the dyngroup cache with the compiled/resolved filter for
+            // Insert it to the dyngroup cache with the parsed filter for
             // fast matching in other paths.
             if dyn_groups.insts.insert(uuid, scope_i).is_none() == expect {
                 error!("{} cache uuid conflict {}", Attribute::DynGroup, uuid);
@@ -175,6 +175,11 @@ impl DynGroup {
     ) -> Result<BTreeSet<Uuid>, OperationError> {
         let mut affected_uuids = BTreeSet::new();
 
+        if qs.get_phase() < ServerPhase::SchemaReady {
+            debug!("Server is not ready to apply dyngroups");
+            return Ok(affected_uuids);
+        }
+
         let ident_internal = Identity::from_internal();
 
         let (n_dyn_groups, entries): (Vec<&Entry<_, _>>, Vec<_>) = cand.iter().partition(|entry| {
@@ -202,9 +207,7 @@ impl DynGroup {
             let dg_filter_valid = dg_filter
                 .validate(qs.get_schema())
                 .map_err(OperationError::SchemaViolation)
-                .and_then(|f| {
-                    f.resolve(&ident_internal, None, Some(qs.get_resolve_filter_cache()))
-                })?;
+                .and_then(|f| f.resolve(&ident_internal, None, qs.get_resolve_filter_cache()))?;
 
             // Did any of our modified entries match our dyn group filter?
             let matches: Vec<_> = entries
@@ -291,6 +294,11 @@ impl DynGroup {
     ) -> Result<BTreeSet<Uuid>, OperationError> {
         let mut affected_uuids = BTreeSet::new();
 
+        if qs.get_phase() < ServerPhase::SchemaReady {
+            debug!("Server is not ready to apply dyngroups");
+            return Ok(affected_uuids);
+        }
+
         let ident_internal = Identity::from_internal();
 
         // Probably should be filter here instead.
@@ -338,9 +346,7 @@ impl DynGroup {
             let dg_filter_valid = dg_filter
                 .validate(qs.get_schema())
                 .map_err(OperationError::SchemaViolation)
-                .and_then(|f| {
-                    f.resolve(&ident_internal, None, Some(qs.get_resolve_filter_cache()))
-                })?;
+                .and_then(|f| f.resolve(&ident_internal, None, qs.get_resolve_filter_cache()))?;
 
             let matches: Vec<_> = pre_entries
                 .iter()
diff --git a/server/lib/src/repl/consumer.rs b/server/lib/src/repl/consumer.rs
index 03e269517..16449e9a0 100644
--- a/server/lib/src/repl/consumer.rs
+++ b/server/lib/src/repl/consumer.rs
@@ -1,7 +1,7 @@
 use super::proto::*;
 use crate::plugins::Plugins;
 use crate::prelude::*;
-use crate::server::ChangeFlag;
+use crate::server::{ChangeFlag, ServerPhase};
 use std::collections::{BTreeMap, BTreeSet};
 use std::sync::Arc;
 
@@ -343,7 +343,7 @@ impl QueryServerWriteTransaction<'_> {
         }
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "info", skip_all)]
     fn consumer_apply_changes_v1(
         &mut self,
         ctx_domain_version: DomainVersion,
@@ -548,7 +548,7 @@ impl QueryServerWriteTransaction<'_> {
         Ok(())
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "info", skip_all)]
     fn consumer_apply_refresh_v1(
         &mut self,
         ctx_domain_version: DomainVersion,
@@ -583,6 +583,7 @@ impl QueryServerWriteTransaction<'_> {
         };
 
         // == ⚠️  Below this point we begin to make changes! ==
+        self.set_phase_bootstrap();
 
         // Update the d_uuid. This is what defines us as being part of this repl topology!
         self.be_txn
@@ -597,7 +598,6 @@ impl QueryServerWriteTransaction<'_> {
         self.reset_server_uuid()?;
 
         // Delete all entries - *proper delete, not just tombstone!*
-
         self.be_txn
             .danger_delete_all_db_content()
             .inspect_err(|err| {
@@ -609,6 +609,12 @@ impl QueryServerWriteTransaction<'_> {
             error!(?err, "Failed to reset in memory schema to clean state");
         })?;
 
+        // Reindex now to force some basic indexes to exist as we consume the schema
+        // from our replica.
+        self.reindex(false).inspect_err(|err| {
+            error!(?err, "Failed to reload schema");
+        })?;
+
         // Apply the schema entries first. This is the foundation that everything
         // else will build upon!
         self.consumer_refresh_create_entries(ctx_schema_entries)
@@ -621,6 +627,9 @@ impl QueryServerWriteTransaction<'_> {
             error!(?err, "Failed to reload schema");
         })?;
 
+        // Schema is now ready
+        self.set_phase(ServerPhase::SchemaReady);
+
         // We have to reindex to force all the existing indexes to be dumped
         // and recreated before we start to import.
         self.reindex(false).inspect_err(|err| {
@@ -652,7 +661,10 @@ impl QueryServerWriteTransaction<'_> {
                 | ChangeFlag::KEY_MATERIAL,
         );
 
-        // That's it! We are GOOD to go!
+        // Domain info is now ready.
+        self.set_phase(ServerPhase::DomainInfoReady);
+
+        // ==== That's it! We are GOOD to go! ====
 
         // Create all the entries. Note we don't hit plugins here beside post repl plugs.
         self.consumer_refresh_create_entries(ctx_entries)
@@ -672,6 +684,9 @@ impl QueryServerWriteTransaction<'_> {
             error!(?err, "Unable to update RUV with supplier ranges.");
         })?;
 
+        // Refresh complete
+        self.set_phase(ServerPhase::Running);
+
         Ok(())
     }
 }
diff --git a/server/lib/src/schema.rs b/server/lib/src/schema.rs
index 88937aed3..4f7c55a34 100644
--- a/server/lib/src/schema.rs
+++ b/server/lib/src/schema.rs
@@ -16,16 +16,14 @@
 //! [`Attributes`]: struct.SchemaAttribute.html
 //! [`Classes`]: struct.SchemaClass.html
 
-use std::collections::BTreeSet;
-
-use concread::cowcell::*;
-use hashbrown::{HashMap, HashSet};
-use tracing::trace;
-use uuid::Uuid;
-
 use crate::be::IdxKey;
 use crate::prelude::*;
 use crate::valueset::ValueSet;
+use concread::cowcell::*;
+use hashbrown::{HashMap, HashSet};
+use std::collections::BTreeSet;
+use tracing::trace;
+use uuid::Uuid;
 
 // representations of schema that confines object types, classes
 // and attributes. This ties in deeply with "Entry".
@@ -70,6 +68,31 @@ pub struct SchemaReadTransaction {
     ref_cache: CowCellReadTxn<HashMap<Attribute, SchemaAttribute>>,
 }
 
+#[derive(Debug, Clone, Copy, Default)]
+pub enum Replicated {
+    #[default]
+    True,
+    False,
+}
+
+impl From<Replicated> for bool {
+    fn from(value: Replicated) -> bool {
+        match value {
+            Replicated::True => true,
+            Replicated::False => false,
+        }
+    }
+}
+
+impl From<bool> for Replicated {
+    fn from(value: bool) -> Self {
+        match value {
+            true => Replicated::True,
+            false => Replicated::False,
+        }
+    }
+}
+
 /// An item representing an attribute and the rules that enforce it. These rules enforce if an
 /// attribute on an [`Entry`] may be single or multi value, must be unique amongst all other types
 /// of this attribute, if the attribute should be [`indexed`], and what type of data [`syntax`] it may hold.
@@ -81,21 +104,23 @@ pub struct SchemaReadTransaction {
 pub struct SchemaAttribute {
     pub name: Attribute,
     pub uuid: Uuid,
-    // Perhaps later add aliases?
     pub description: String,
-    /// This is a vec, not a single value
+    /// Defines if the attribute may have one or multiple values associated to it.
     pub multivalue: bool,
-    /// If the attribute must be unique amongst all other values of this attribute? Maybe?
+    /// If this flag is set, all instances of this attribute must be a unique value in the database.
     pub unique: bool,
-    /// TODO: What does this do?
+    /// This defines that the value is a phantom - it is "not real", can never "be real". It
+    /// is synthesised in memory, and will never be written to the database. This can exist for
+    /// placeholders like cn/uid in ldap.
     pub phantom: bool,
-    /// TODO: What does this do?
+    /// This boolean defines if this attribute may be altered by an external IDP sync
+    /// agreement.
     pub sync_allowed: bool,
 
-    /// If the value of this attribute get replicated to other servers
-    pub replicated: bool,
-    /// TODO: What does this do?
-    pub index: Vec<IndexType>,
+    /// If set the value of this attribute get replicated to other servers
+    pub replicated: Replicated,
+    /// Define if this attribute is indexed or not according to its syntax type rule
+    pub indexed: bool,
     /// THe type of data that this attribute may hold.
     pub syntax: SyntaxType,
 }
@@ -144,6 +169,7 @@ impl SchemaAttribute {
                 admin_error!("missing {} - {}", Attribute::MultiValue, name);
                 OperationError::InvalidSchemaState("missing multivalue".to_string())
             })?;
+
         let unique = value
             .get_ava_single_bool(Attribute::Unique)
             .ok_or_else(|| {
@@ -153,25 +179,23 @@ impl SchemaAttribute {
 
         let phantom = value
             .get_ava_single_bool(Attribute::Phantom)
-            .unwrap_or(false);
+            .unwrap_or_default();
 
         let sync_allowed = value
             .get_ava_single_bool(Attribute::SyncAllowed)
-            .unwrap_or(false);
+            .unwrap_or_default();
 
         // Default, all attributes are replicated unless you opt in for them to NOT be.
         // Generally this is internal to the server only, so we don't advertise it.
         let replicated = value
             .get_ava_single_bool(Attribute::Replicated)
-            .unwrap_or(true);
+            .map(Replicated::from)
+            .unwrap_or_default();
+
+        let indexed = value
+            .get_ava_single_bool(Attribute::Indexed)
+            .unwrap_or_default();
 
-        // index vec
-        // even if empty, it SHOULD be present ... (is that valid to put an empty set?)
-        // The get_ava_opt_index handles the optional case for us :)
-        let index = value.get_ava_opt_index(Attribute::Index).ok_or_else(|| {
-            admin_error!("invalid {} - {}", Attribute::Index, name);
-            OperationError::InvalidSchemaState(format!("invalid {}", Attribute::Index))
-        })?;
         // syntax type
         let syntax = value
             .get_ava_single_syntax(Attribute::Syntax)
@@ -180,6 +204,8 @@ impl SchemaAttribute {
                 OperationError::InvalidSchemaState(format!("missing {}", Attribute::Syntax))
             })?;
 
+        trace!(?name, ?indexed);
+
         Ok(SchemaAttribute {
             name,
             uuid,
@@ -189,7 +215,7 @@ impl SchemaAttribute {
             phantom,
             sync_allowed,
             replicated,
-            index,
+            indexed,
             syntax,
         })
     }
@@ -357,51 +383,6 @@ impl SchemaAttribute {
     }
 }
 
-impl From<SchemaAttribute> for EntryInitNew {
-    fn from(value: SchemaAttribute) -> Self {
-        let mut entry = EntryInitNew::new();
-
-        entry.set_ava(
-            Attribute::AttributeName,
-            vec![Value::new_iutf8(value.name.as_str())],
-        );
-        entry.add_ava(Attribute::MultiValue, Value::Bool(value.multivalue));
-        // syntax
-        entry.set_ava(Attribute::Syntax, vec![Value::Syntax(value.syntax)]);
-        entry.set_ava(Attribute::Unique, vec![Value::Bool(value.unique)]);
-        // index
-        entry.set_ava(Attribute::Index, value.index.into_iter().map(Value::Index));
-
-        // class
-        entry.set_ava(
-            Attribute::Class,
-            vec![
-                EntryClass::Object.to_value(),
-                EntryClass::System.into(),
-                EntryClass::AttributeType.to_value(),
-            ],
-        );
-        // description
-        entry.set_ava(
-            Attribute::Description,
-            vec![Value::new_utf8s(&value.description)],
-        );
-        // unique
-        // multivalue
-
-        // sync_allowed
-        entry.set_ava(
-            Attribute::SyncAllowed,
-            vec![Value::Bool(value.sync_allowed)],
-        );
-
-        // uid
-        entry.set_ava(Attribute::Uuid, vec![Value::Uuid(value.uuid)]);
-
-        entry
-    }
-}
-
 /// An item representing a class and the rules for that class. These rules enforce that an
 /// [`Entry`]'s avas conform to a set of requirements, giving structure to an entry about
 /// what avas must or may exist. The kanidm project provides attributes in `systemmust` and
@@ -541,73 +522,6 @@ impl SchemaClass {
     }
 }
 
-impl From<SchemaClass> for EntryInitNew {
-    fn from(value: SchemaClass) -> Self {
-        let mut entry = EntryInitNew::new();
-
-        entry.set_ava(Attribute::ClassName, vec![Value::new_iutf8(&value.name)]);
-
-        // class
-        entry.set_ava(
-            Attribute::Class,
-            vec![
-                EntryClass::Object.to_value(),
-                EntryClass::System.into(),
-                EntryClass::ClassType.into(),
-            ],
-        );
-
-        // description
-        entry.set_ava(
-            Attribute::Description,
-            vec![Value::new_utf8s(&value.description)],
-        );
-
-        // sync_allowed
-        entry.set_ava(
-            Attribute::SyncAllowed,
-            vec![Value::Bool(value.sync_allowed)],
-        );
-
-        // uid
-        entry.set_ava(Attribute::Uuid, vec![Value::Uuid(value.uuid)]);
-
-        // systemmay
-        if !value.systemmay.is_empty() {
-            entry.set_ava(
-                Attribute::SystemMay,
-                value.systemmay.iter().map(|s| Value::new_iutf8(s.as_str())),
-            );
-        }
-        // systemexcludes
-        if !value.systemexcludes.is_empty() {
-            entry.set_ava(
-                Attribute::SystemExcludes,
-                value.systemexcludes.iter().map(|s| Value::new_iutf8(s)),
-            );
-        }
-        // systemmust
-        if !value.systemmust.is_empty() {
-            entry.set_ava(
-                Attribute::SystemMust,
-                value
-                    .systemmust
-                    .iter()
-                    .map(|s| Value::new_iutf8(s.as_str())),
-            );
-        }
-        // systemsupplements
-        if !value.systemsupplements.is_empty() {
-            entry.set_ava(
-                Attribute::SystemSupplements,
-                value.systemsupplements.iter().map(|s| Value::new_iutf8(s)),
-            );
-        }
-
-        entry
-    }
-}
-
 pub trait SchemaTransaction {
     fn get_classes(&self) -> &HashMap<AttrString, SchemaClass>;
     fn get_attributes(&self) -> &HashMap<Attribute, SchemaAttribute>;
@@ -674,7 +588,7 @@ pub trait SchemaTransaction {
             Some(a_schema) => {
                 // We'll likely add more conditions here later.
                 // Allow items that are replicated and not phantoms
-                a_schema.replicated && !a_schema.phantom
+                a_schema.replicated.into() && !a_schema.phantom
             }
             None => {
                 warn!(
@@ -846,7 +760,14 @@ impl SchemaWriteTransaction<'_> {
         self.get_attributes()
             .values()
             .flat_map(|a| {
-                a.index.iter().map(move |itype: &IndexType| IdxKey {
+                // Unique values must be indexed
+                if a.indexed || a.unique {
+                    a.syntax.index_types()
+                } else {
+                    &[]
+                }
+                .iter()
+                .map(move |itype: &IndexType| IdxKey {
                     attr: a.name.clone(),
                     itype: *itype,
                 })
@@ -871,8 +792,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality, IndexType::Presence],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -888,8 +809,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality, IndexType::Presence],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Uuid,
             },
         );
@@ -907,8 +828,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality, IndexType::Presence],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Uuid,
             },
         );
@@ -924,8 +845,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Cid,
             },
         );
@@ -941,8 +862,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Cid,
             },
         );
@@ -956,12 +877,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: true,
-                replicated: true,
-                index: vec![
-                    IndexType::Equality,
-                    IndexType::Presence,
-                    IndexType::SubString,
-                ],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringIname,
             },
         );
@@ -977,8 +894,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::SecurityPrincipalName,
             },
         );
@@ -992,8 +909,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1007,8 +924,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1022,8 +939,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: true,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1035,8 +952,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             });
         self.attributes.insert(Attribute::Phantom, SchemaAttribute {
@@ -1047,8 +964,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             });
         self.attributes.insert(Attribute::SyncAllowed, SchemaAttribute {
@@ -1059,8 +976,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             });
         self.attributes.insert(Attribute::Replicated, SchemaAttribute {
@@ -1071,8 +988,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             });
         self.attributes.insert(
@@ -1087,8 +1004,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             },
         );
@@ -1104,11 +1021,28 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::IndexId,
             },
         );
+        self.attributes.insert(
+            Attribute::Indexed,
+            SchemaAttribute {
+                name: Attribute::Indexed,
+                uuid: UUID_SCHEMA_ATTR_INDEXED,
+                description: String::from(
+                    "A boolean stating if this attribute will be indexed according to its syntax rules."
+                ),
+                multivalue: false,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: false,
+                syntax: SyntaxType::Boolean,
+            },
+        );
         self.attributes.insert(
             Attribute::Syntax,
             SchemaAttribute {
@@ -1121,8 +1055,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::SyntaxId,
             },
         );
@@ -1138,8 +1072,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1155,8 +1089,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1172,8 +1106,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1189,45 +1123,45 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
         self.attributes.insert(
-                Attribute::SystemSupplements,
-                SchemaAttribute {
-                    name: Attribute::SystemSupplements,
-                    uuid: UUID_SCHEMA_ATTR_SYSTEMSUPPLEMENTS,
-                    description: String::from(
-                        "A set of classes that this type supplements too, where this class can't exist without their presence.",
-                    ),
-                    multivalue: true,
-                    unique: false,
-                    phantom: false,
-                    sync_allowed: false,
-                    replicated: true,
-                    index: vec![],
-                    syntax: SyntaxType::Utf8StringInsensitive,
-                },
-            );
+            Attribute::SystemSupplements,
+            SchemaAttribute {
+                name: Attribute::SystemSupplements,
+                uuid: UUID_SCHEMA_ATTR_SYSTEMSUPPLEMENTS,
+                description: String::from(
+                    "A set of classes that this type supplements, where this class can't exist without their presence.",
+                ),
+                multivalue: true,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: false,
+                syntax: SyntaxType::Utf8StringInsensitive,
+            },
+        );
         self.attributes.insert(
-                Attribute::Supplements,
-                SchemaAttribute {
-                    name: Attribute::Supplements,
-                    uuid: UUID_SCHEMA_ATTR_SUPPLEMENTS,
-                    description: String::from(
-                        "A set of user modifiable classes, where this determines that at least one other type must supplement this type",
-                    ),
-                    multivalue: true,
-                    unique: false,
-                    phantom: false,
-                    sync_allowed: false,
-                    replicated: true,
-                    index: vec![],
-                    syntax: SyntaxType::Utf8StringInsensitive,
-                },
-            );
+            Attribute::Supplements,
+            SchemaAttribute {
+                name: Attribute::Supplements,
+                uuid: UUID_SCHEMA_ATTR_SUPPLEMENTS,
+                description: String::from(
+                    "A set of user modifiable classes, where this determines that at least one other type must supplement this type",
+                ),
+                multivalue: true,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: false,
+                syntax: SyntaxType::Utf8StringInsensitive,
+            },
+        );
         self.attributes.insert(
             Attribute::SystemExcludes,
             SchemaAttribute {
@@ -1240,46 +1174,46 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
         self.attributes.insert(
-                Attribute::Excludes,
-                SchemaAttribute {
-                    name: Attribute::Excludes,
-                    uuid: UUID_SCHEMA_ATTR_EXCLUDES,
-                    description: String::from(
-                        "A set of user modifiable classes that are denied presence in connection to this class",
-                    ),
-                    multivalue: true,
-                    unique: false,
-                    phantom: false,
-                    sync_allowed: false,
-                    replicated: true,
-                    index: vec![],
-                    syntax: SyntaxType::Utf8StringInsensitive,
-                },
-            );
+            Attribute::Excludes,
+            SchemaAttribute {
+                name: Attribute::Excludes,
+                uuid: UUID_SCHEMA_ATTR_EXCLUDES,
+                description: String::from(
+                    "A set of user modifiable classes that are denied presence in connection to this class",
+                ),
+                multivalue: true,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: false,
+                syntax: SyntaxType::Utf8StringInsensitive,
+            },
+        );
 
         // SYSINFO attrs
         // ACP attributes.
         self.attributes.insert(
-                Attribute::AcpEnable,
-                SchemaAttribute {
-                    name: Attribute::AcpEnable,
-                    uuid: UUID_SCHEMA_ATTR_ACP_ENABLE,
-                    description: String::from("A flag to determine if this ACP is active for application. True is enabled, and enforce. False is checked but not enforced."),
-                    multivalue: false,
-                    unique: false,
-                    phantom: false,
-                    sync_allowed: false,
-                    replicated: true,
-                    index: vec![IndexType::Equality],
-                    syntax: SyntaxType::Boolean,
-                },
-            );
+            Attribute::AcpEnable,
+            SchemaAttribute {
+                name: Attribute::AcpEnable,
+                uuid: UUID_SCHEMA_ATTR_ACP_ENABLE,
+                description: String::from("A flag to determine if this ACP is active for application. True is enabled, and enforced. False is checked but not enforced."),
+                multivalue: false,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: true,
+                syntax: SyntaxType::Boolean,
+            },
+        );
 
         self.attributes.insert(
             Attribute::AcpReceiver,
@@ -1293,8 +1227,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::JsonFilter,
             },
         );
@@ -1310,8 +1244,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1328,8 +1262,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::JsonFilter,
             },
         );
@@ -1345,8 +1279,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1360,8 +1294,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1377,8 +1311,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1395,8 +1329,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1412,26 +1346,26 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
         self.attributes.insert(
-                Attribute::AcpModifyClass,
-                SchemaAttribute {
-                    name: Attribute::AcpModifyClass,
-                    uuid: UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS,
-                    description: String::from("The set of class values that could be asserted or added to an entry. Only applies to modify::present operations on class."),
-                    multivalue: true,
-                    unique: false,
-                    phantom: false,
-                    sync_allowed: false,
-                    replicated: true,
-                    index: vec![IndexType::Equality],
-                    syntax: SyntaxType::Utf8StringInsensitive,
-                },
-            );
+            Attribute::AcpModifyClass,
+            SchemaAttribute {
+                name: Attribute::AcpModifyClass,
+                uuid: UUID_SCHEMA_ATTR_ACP_MODIFY_CLASS,
+                description: String::from("The set of class values that could be asserted or added to an entry. Only applies to modify::present operations on class."),
+                multivalue: true,
+                unique: false,
+                phantom: false,
+                sync_allowed: false,
+                replicated: Replicated::True,
+                indexed: true,
+                syntax: SyntaxType::Utf8StringInsensitive,
+            },
+        );
         self.attributes.insert(
             Attribute::EntryManagedBy,
             SchemaAttribute {
@@ -1444,8 +1378,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1460,8 +1394,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::False,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1475,8 +1409,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::False,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1494,8 +1428,8 @@ impl SchemaWriteTransaction<'_> {
                 //  "at delete" are replicated to partners. This avoids us having to replicate
                 // DMO which is very costly, while still retaining our ability to revive entries
                 // and their group memberships as a best effort.
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1509,8 +1443,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: true,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1524,8 +1458,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: true,
-                replicated: false,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::False,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1542,8 +1476,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Uint32,
             },
         );
@@ -1558,8 +1492,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringIname,
             },
         );
@@ -1575,8 +1509,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1592,8 +1526,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1611,8 +1545,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1628,8 +1562,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![IndexType::Equality],
+                replicated: Replicated::True,
+                indexed: true,
                 syntax: SyntaxType::ReferenceUuid,
             },
         );
@@ -1643,8 +1577,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1659,8 +1593,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: true,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1677,8 +1611,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: true,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1693,8 +1627,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: true,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::TotpSecret,
             },
         );
@@ -1710,8 +1644,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1725,8 +1659,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1740,8 +1674,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Uuid,
             },
         );
@@ -1755,8 +1689,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringInsensitive,
             },
         );
@@ -1770,8 +1704,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8StringIname,
             },
         );
@@ -1785,8 +1719,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::SshKey,
             },
         );
@@ -1800,8 +1734,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::SshKey,
             },
         );
@@ -1815,8 +1749,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::EmailAddress,
             },
         );
@@ -1830,8 +1764,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::EmailAddress,
             },
         );
@@ -1845,8 +1779,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::EmailAddress,
             },
         );
@@ -1860,8 +1794,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::EmailAddress,
             },
         );
@@ -1875,8 +1809,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1890,8 +1824,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1905,8 +1839,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Uint32,
             },
         );
@@ -1920,8 +1854,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: true,
                 sync_allowed: false,
-                replicated: false,
-                index: vec![],
+                replicated: Replicated::False,
+                indexed: false,
                 syntax: SyntaxType::Utf8String,
             },
         );
@@ -1936,8 +1870,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: false,
                 phantom: false,
                 sync_allowed: true,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Image,
             },
         );
@@ -1952,8 +1886,8 @@ impl SchemaWriteTransaction<'_> {
                 unique: true,
                 phantom: false,
                 sync_allowed: false,
-                replicated: true,
-                index: vec![],
+                replicated: Replicated::True,
+                indexed: false,
                 syntax: SyntaxType::Boolean,
             },
         );
@@ -1969,6 +1903,7 @@ impl SchemaWriteTransaction<'_> {
                     Attribute::Phantom,
                     Attribute::SyncAllowed,
                     Attribute::Index,
+                    Attribute::Indexed,
                 ],
                 systemmust: vec![
                     Attribute::Class,
@@ -2317,30 +2252,12 @@ impl Schema {
     pub(crate) fn write_blocking(&self) -> SchemaWriteTransaction<'_> {
         self.write()
     }
-
-    /*
-    pub async fn write<'a>(&'a self) -> SchemaWriteTransaction<'a> {
-        SchemaWriteTransaction {
-            classes: self.classes.write().await,
-            attributes: self.attributes.write().await,
-            unique_cache: self.unique_cache.write().await,
-            ref_cache: self.ref_cache.write().await,
-        }
-    }
-
-    #[cfg(test)]
-    pub fn write_blocking<'a>(&'a self) -> SchemaWriteTransaction<'a> {
-        task::block_on(self.write())
-    }
-    */
 }
 
 #[cfg(test)]
 mod tests {
     use crate::prelude::*;
-    use crate::schema::{
-        IndexType, Schema, SchemaAttribute, SchemaClass, SchemaTransaction, SyntaxType,
-    };
+    use crate::schema::{Schema, SchemaAttribute, SchemaClass, SchemaTransaction, SyntaxType};
     use uuid::Uuid;
 
     // use crate::proto_v1::Filter as ProtoFilter;
@@ -2379,6 +2296,8 @@ mod tests {
 
     #[test]
     fn test_schema_attribute_from_entry() {
+        sketching::test_init();
+
         sch_from_entry_err!(
             entry_init!(
                 (Attribute::Class, EntryClass::Object.to_value()),
@@ -2410,8 +2329,7 @@ mod tests {
                 ),
                 (Attribute::MultiValue, Value::Bool(false)),
                 (Attribute::Unique, Value::Bool(false)),
-                (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
-                (Attribute::Index, Value::Index(IndexType::Equality))
+                (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String))
             ),
             SchemaAttribute
         );
@@ -2434,8 +2352,7 @@ mod tests {
                 ),
                 (Attribute::MultiValue, Value::Utf8("htouaoeu".to_string())),
                 (Attribute::Unique, Value::Bool(false)),
-                (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
-                (Attribute::Index, Value::Index(IndexType::Equality))
+                (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String))
             ),
             SchemaAttribute
         );
@@ -2458,32 +2375,7 @@ mod tests {
                 ),
                 (Attribute::MultiValue, Value::Bool(false)),
                 (Attribute::Unique, Value::Bool(false)),
-                (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
-                (Attribute::Index, Value::Utf8("NTEHNOU".to_string()))
-            ),
-            SchemaAttribute
-        );
-
-        sch_from_entry_err!(
-            entry_init!(
-                (Attribute::Class, EntryClass::Object.to_value()),
-                (Attribute::Class, EntryClass::AttributeType.to_value()),
-                (
-                    Attribute::AttributeName,
-                    Value::new_iutf8("schema_attr_test")
-                ),
-                (
-                    Attribute::Uuid,
-                    Value::Uuid(uuid::uuid!("66c68b2f-d02c-4243-8013-7946e40fe321"))
-                ),
-                (
-                    Attribute::Description,
-                    Value::Utf8("Test attr parsing".to_string())
-                ),
-                (Attribute::MultiValue, Value::Bool(false)),
-                (Attribute::Unique, Value::Bool(false)),
-                (Attribute::Syntax, Value::Utf8("TNEOUNTUH".to_string())),
-                (Attribute::Index, Value::Index(IndexType::Equality))
+                (Attribute::Syntax, Value::Utf8("TNEOUNTUH".to_string()))
             ),
             SchemaAttribute
         );
@@ -2532,7 +2424,7 @@ mod tests {
                 (Attribute::MultiValue, Value::Bool(false)),
                 (Attribute::Unique, Value::Bool(false)),
                 (Attribute::Syntax, Value::Syntax(SyntaxType::Utf8String)),
-                (Attribute::Index, Value::Index(IndexType::Equality))
+                (Attribute::Index, Value::Bool(true))
             ),
             SchemaAttribute
         );
@@ -2674,7 +2566,6 @@ mod tests {
             name: Attribute::from("single_value"),
             uuid: Uuid::new_v4(),
             description: String::from(""),
-            index: vec![IndexType::Equality],
             syntax: SyntaxType::Utf8StringInsensitive,
             ..Default::default()
         };
@@ -2699,7 +2590,6 @@ mod tests {
             uuid: Uuid::new_v4(),
             description: String::from(""),
             multivalue: true,
-            index: vec![IndexType::Equality],
             syntax: SyntaxType::Utf8String,
             ..Default::default()
         };
@@ -2713,7 +2603,6 @@ mod tests {
             uuid: Uuid::new_v4(),
             description: String::from(""),
             multivalue: true,
-            index: vec![IndexType::Equality],
             syntax: SyntaxType::Boolean,
             ..Default::default()
         };
@@ -2743,7 +2632,6 @@ mod tests {
             name: Attribute::from("sv_syntax"),
             uuid: Uuid::new_v4(),
             description: String::from(""),
-            index: vec![IndexType::Equality],
             syntax: SyntaxType::SyntaxId,
             ..Default::default()
         };
@@ -2763,14 +2651,9 @@ mod tests {
             name: Attribute::from("sv_index"),
             uuid: Uuid::new_v4(),
             description: String::from(""),
-            index: vec![IndexType::Equality],
             syntax: SyntaxType::IndexId,
             ..Default::default()
         };
-        //
-        let rvs = vs_index![IndexType::try_from("EQUALITY").unwrap()] as _;
-        let r8 = single_value_index.validate_ava(&Attribute::from("sv_index"), &rvs);
-        assert_eq!(r8, Ok(()));
 
         let rvs = vs_utf8!["thaeountaheu".to_string()] as _;
         let r9 = single_value_index.validate_ava(&Attribute::from("sv_index"), &rvs);
diff --git a/server/lib/src/server/mod.rs b/server/lib/src/server/mod.rs
index 8c6f605be..29a962958 100644
--- a/server/lib/src/server/mod.rs
+++ b/server/lib/src/server/mod.rs
@@ -31,7 +31,7 @@ use crate::value::{CredentialType, EXTRACT_VAL_DN};
 use crate::valueset::uuid_to_proto_string;
 use crate::valueset::ScimValueIntermediate;
 use crate::valueset::*;
-use concread::arcache::{ARCacheBuilder, ARCacheReadTxn};
+use concread::arcache::{ARCacheBuilder, ARCacheReadTxn, ARCacheWriteTxn};
 use concread::cowcell::*;
 use hashbrown::{HashMap, HashSet};
 use kanidm_proto::internal::{DomainInfo as ProtoDomainInfo, ImageValue, UiHint};
@@ -205,6 +205,13 @@ pub struct QueryServerWriteTransaction<'a> {
     pub(super) changed_uuid: HashSet<Uuid>,
     _db_ticket: SemaphorePermit<'a>,
     _write_ticket: SemaphorePermit<'a>,
+    resolve_filter_cache_clear: bool,
+    resolve_filter_cache_write: ARCacheWriteTxn<
+        'a,
+        (IdentityId, Arc<Filter<FilterValid>>),
+        Arc<Filter<FilterValidResolved>>,
+        (),
+    >,
     resolve_filter_cache: ARCacheReadTxn<
         'a,
         (IdentityId, Arc<Filter<FilterValid>>),
@@ -260,7 +267,7 @@ pub trait QueryServerTransaction<'a> {
 
     fn get_domain_image_value(&self) -> Option<ImageValue>;
 
-    fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a>;
+    fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>>;
 
     // Because of how borrowck in rust works, if we need to get two inner types we have to get them
     // in a single fn.
@@ -269,7 +276,7 @@ pub trait QueryServerTransaction<'a> {
         &mut self,
     ) -> (
         &mut Self::BackendTransactionType,
-        &mut ResolveFilterCacheReadTxn<'a>,
+        Option<&mut ResolveFilterCacheReadTxn<'a>>,
     );
 
     /// Conduct a search and apply access controls to yield a set of entries that
@@ -326,11 +333,15 @@ pub trait QueryServerTransaction<'a> {
         // NOTE: Filters are validated in event conversion.
 
         let (be_txn, resolve_filter_cache) = self.get_resolve_filter_cache_and_be_txn();
+
         let idxmeta = be_txn.get_idxmeta_ref();
+
+        trace!(resolve_filter_cache = %resolve_filter_cache.is_some());
+
         // Now resolve all references and indexes.
         let vfr = se
             .filter
-            .resolve(&se.ident, Some(idxmeta), Some(resolve_filter_cache))
+            .resolve(&se.ident, Some(idxmeta), resolve_filter_cache)
             .map_err(|e| {
                 admin_error!(?e, "search filter resolve failure");
                 e
@@ -366,7 +377,7 @@ pub trait QueryServerTransaction<'a> {
 
         let vfr = ee
             .filter
-            .resolve(&ee.ident, Some(idxmeta), Some(resolve_filter_cache))
+            .resolve(&ee.ident, Some(idxmeta), resolve_filter_cache)
             .map_err(|e| {
                 admin_error!(?e, "Failed to resolve filter");
                 e
@@ -1444,17 +1455,17 @@ impl<'a> QueryServerTransaction<'a> for QueryServerReadTransaction<'a> {
         &self.key_providers
     }
 
-    fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a> {
-        &mut self.resolve_filter_cache
+    fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>> {
+        Some(&mut self.resolve_filter_cache)
     }
 
     fn get_resolve_filter_cache_and_be_txn(
         &mut self,
     ) -> (
         &mut BackendReadTransaction<'a>,
-        &mut ResolveFilterCacheReadTxn<'a>,
+        Option<&mut ResolveFilterCacheReadTxn<'a>>,
     ) {
-        (&mut self.be_txn, &mut self.resolve_filter_cache)
+        (&mut self.be_txn, Some(&mut self.resolve_filter_cache))
     }
 
     fn pw_badlist(&self) -> &HashSet<String> {
@@ -1678,17 +1689,25 @@ impl<'a> QueryServerTransaction<'a> for QueryServerWriteTransaction<'a> {
         &self.key_providers
     }
 
-    fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a> {
-        &mut self.resolve_filter_cache
+    fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>> {
+        if self.resolve_filter_cache_clear || *self.phase < ServerPhase::SchemaReady {
+            None
+        } else {
+            Some(&mut self.resolve_filter_cache)
+        }
     }
 
     fn get_resolve_filter_cache_and_be_txn(
         &mut self,
     ) -> (
         &mut BackendWriteTransaction<'a>,
-        &mut ResolveFilterCacheReadTxn<'a>,
+        Option<&mut ResolveFilterCacheReadTxn<'a>>,
     ) {
-        (&mut self.be_txn, &mut self.resolve_filter_cache)
+        if self.resolve_filter_cache_clear || *self.phase < ServerPhase::SchemaReady {
+            (&mut self.be_txn, None)
+        } else {
+            (&mut self.be_txn, Some(&mut self.resolve_filter_cache))
+        }
     }
 
     fn pw_badlist(&self) -> &HashSet<String> {
@@ -2003,6 +2022,8 @@ impl QueryServer {
             _db_ticket: db_ticket,
             _write_ticket: write_ticket,
             resolve_filter_cache: self.resolve_filter_cache.read(),
+            resolve_filter_cache_clear: false,
+            resolve_filter_cache_write: self.resolve_filter_cache.write(),
             dyngroup_cache: self.dyngroup_cache.write(),
             key_providers: self.key_providers.write(),
         })
@@ -2152,16 +2173,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
             ))
         }?;
 
-        // TODO: Clear the filter resolve cache.
-        // currently we can't do this because of the limits of types with arccache txns. The only
-        // thing this impacts is if something in indexed though, and the backend does handle
-        // incorrectly indexed items correctly.
+        // Since we reloaded the schema, we need to reload the filter cache since it
+        // may have incorrect or outdated information about indexes now.
+        self.resolve_filter_cache_clear = true;
 
         // Trigger reloads on services that require post-schema reloads.
         // Mainly this is plugins.
-        if *self.phase >= ServerPhase::SchemaReady {
-            DynGroup::reload(self)?;
-        }
+        DynGroup::reload(self)?;
 
         Ok(())
     }
@@ -2584,7 +2602,14 @@ impl<'a> QueryServerWriteTransaction<'a> {
         self.changed_flags.remove(ChangeFlag::OAUTH2)
     }
 
-    fn set_phase(&mut self, phase: ServerPhase) {
+    /// Indicate that we are about to re-bootstrap this server. You should ONLY
+    /// call this during a replication refresh!!!
+    pub(crate) fn set_phase_bootstrap(&mut self) {
+        *self.phase = ServerPhase::Bootstrap;
+    }
+
+    /// Raise the currently running server phase.
+    pub(crate) fn set_phase(&mut self, phase: ServerPhase) {
         // Phase changes are one way
         if phase > *self.phase {
             *self.phase = phase
@@ -2698,6 +2723,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
             changed_flags,
             changed_uuid: _,
             resolve_filter_cache: _,
+            resolve_filter_cache_clear,
+            mut resolve_filter_cache_write,
         } = self;
         debug_assert!(!committed);
 
@@ -2711,6 +2738,12 @@ impl<'a> QueryServerWriteTransaction<'a> {
         be_txn.set_db_ts_max(cid.ts)?;
         cid.commit();
 
+        // We don't care if this passes/fails, committing this is fine.
+        if resolve_filter_cache_clear {
+            resolve_filter_cache_write.clear();
+        }
+        resolve_filter_cache_write.commit();
+
         // Point of no return - everything has been validated and reloaded.
         //
         // = Lets commit =
diff --git a/server/lib/src/value.rs b/server/lib/src/value.rs
index 0bab23b8a..fb3c27ca6 100644
--- a/server/lib/src/value.rs
+++ b/server/lib/src/value.rs
@@ -388,6 +388,65 @@ impl fmt::Display for SyntaxType {
     }
 }
 
+impl SyntaxType {
+    pub fn index_types(&self) -> &[IndexType] {
+        match self {
+            SyntaxType::Utf8String => &[IndexType::Equality, IndexType::Presence],
+            // Used by classes, needs to change ...
+            // Probably need an attrname syntax too
+            SyntaxType::Utf8StringInsensitive => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::Utf8StringIname => &[
+                IndexType::Equality,
+                IndexType::Presence,
+                IndexType::SubString,
+            ],
+            SyntaxType::Uuid => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::Boolean => &[IndexType::Equality],
+            SyntaxType::SyntaxId => &[],
+            SyntaxType::IndexId => &[],
+            SyntaxType::ReferenceUuid => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::JsonFilter => &[],
+            SyntaxType::Credential => &[IndexType::Equality],
+            SyntaxType::SecretUtf8String => &[],
+            SyntaxType::SshKey => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::SecurityPrincipalName => &[
+                IndexType::Equality,
+                IndexType::Presence,
+                IndexType::SubString,
+            ],
+            SyntaxType::Uint32 => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::Cid => &[],
+            SyntaxType::NsUniqueId => &[IndexType::Equality, IndexType::Presence],
+            SyntaxType::DateTime => &[],
+            SyntaxType::EmailAddress => &[IndexType::Equality, IndexType::SubString],
+            SyntaxType::Url => &[],
+            SyntaxType::OauthScope => &[],
+            SyntaxType::OauthScopeMap => &[IndexType::Equality],
+            SyntaxType::PrivateBinary => &[],
+            SyntaxType::IntentToken => &[IndexType::Equality],
+            SyntaxType::Passkey => &[IndexType::Equality],
+            SyntaxType::AttestedPasskey => &[IndexType::Equality],
+            SyntaxType::Session => &[IndexType::Equality],
+            SyntaxType::JwsKeyEs256 => &[],
+            SyntaxType::JwsKeyRs256 => &[],
+            SyntaxType::Oauth2Session => &[IndexType::Equality],
+            SyntaxType::UiHint => &[],
+            SyntaxType::TotpSecret => &[],
+            SyntaxType::ApiToken => &[IndexType::Equality],
+            SyntaxType::AuditLogString => &[],
+            SyntaxType::EcKeyPrivate => &[],
+            SyntaxType::Image => &[],
+            SyntaxType::CredentialType => &[],
+            SyntaxType::WebauthnAttestationCaList => &[],
+            SyntaxType::OauthClaimMap => &[IndexType::Equality],
+            SyntaxType::KeyInternal => &[],
+            SyntaxType::HexString => &[],
+            SyntaxType::Certificate => &[],
+            SyntaxType::ApplicationPassword => &[IndexType::Equality],
+        }
+    }
+}
+
 #[derive(
     Hash,
     Debug,