diff --git a/examples/roles.toml b/examples/roles.toml
index cc61b71..2c91a30 100644
--- a/examples/roles.toml
+++ b/examples/roles.toml
@@ -1,18 +1,17 @@
+[anotherrole]
+
 [testrole]
-name = "Testrole"
 permissions = [
     "lab.test.*"
 ]
 
 [somerole]
-name = "Somerole"
-parents = ["testparent%lmdb"]
+parents = ["testparent/lmdb"]
 permissions = [
     "lab.some.admin"
 ]
 
 [testparent]
-name = "Testparent"
 permissions = [
     "lab.some.write",
     "lab.some.read",
diff --git a/schema b/schema
index 83cd61e..4adb053 160000
--- a/schema
+++ b/schema
@@ -1 +1 @@
-Subproject commit 83cd61e299230f33474e2efa950667d1acfbe085
+Subproject commit 4adb05341763b96a43440a6a96e0d9959ba71e89
diff --git a/src/api/machines.rs b/src/api/machines.rs
index 86f3389..602e194 100644
--- a/src/api/machines.rs
+++ b/src/api/machines.rs
@@ -42,7 +42,8 @@ impl machines::Server for Machines {
         let res = results.get();
         let mut machines = res.init_machines(v.len() as u32);
 
-        for (i, (_name, machine)) in v.into_iter().enumerate() {
+        for (i, (name, machine)) in v.into_iter().enumerate() {
+            debug!(self.session.log, "Adding machine {}: {:?}", name, machine);
             let machine = Arc::new(Machine::new(self.session.clone(), machine, self.db.clone()));
             let mut builder = machines.reborrow().get(i as u32);
             Machine::fill(machine, &mut builder);
diff --git a/src/db/access.rs b/src/db/access.rs
index c34bd90..a47be69 100644
--- a/src/db/access.rs
+++ b/src/db/access.rs
@@ -50,6 +50,10 @@ impl AccessControl {
     pub fn dump_roles(&self) -> Result<Vec<(RoleIdentifier, Role)>> {
         self.internal.dump_roles()
     }
+
+    pub fn get_role(&self, role_id: &RoleIdentifier) -> Result<Option<Role>> {
+        self.internal.get_role(role_id)
+    }
 }
 
 impl fmt::Debug for AccessControl {
@@ -162,37 +166,24 @@ type SourceID = String;
 fn split_once(s: &str, split: char) -> Option<(&str, &str)> {
     s
         .find(split)
-        .map(|idx| s.split_at(idx))
+        .map(|idx| (&s[..idx], &s[(idx+1)..]))
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
 #[serde(try_from = "String")]
+#[serde(into = "String")]
 /// Universal (relative) id of a role
-pub enum RoleIdentifier {
-    /// The role comes from this instance
-    Local {
-        /// Locally unique name for the role. No other role at this instance no matter the source
-        /// may have the same name
-        name: String,
-        /// Role Source, i.e. the database the role comes from
-        source: SourceID,
-    },
-    /// The role comes from a federated instance
-    Remote {
-        /// Name of the role. This role is unique in that instance so the tuple (name, location)
-        /// refers to a unique role
-        name: String,
-        /// The federated instance this role comes from
-        location: String,
-    }
+pub struct RoleIdentifier {
+    /// Locally unique name for the role. No other role at this instance no matter the source
+    /// may have the same name
+    name: String,
+    /// Role Source, i.e. the database the role comes from
+    source: SourceID,
 }
 
 impl fmt::Display for RoleIdentifier {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            RoleIdentifier::Local {name, source} => write!(f, "{}/{}@local", name, source),
-            RoleIdentifier::Remote {name, location} => write!(f, "{}@{}", name, location),
-        }
+        write!(f, "{}/{}", self.name, self.source)
     }
 }
 
@@ -200,10 +191,8 @@ impl std::str::FromStr for RoleIdentifier {
     type Err = RoleFromStrError;
 
     fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
-        if let Some((name, location)) = split_once(s, '@') {
-            Ok(RoleIdentifier::Remote { name: name.to_string(), location: location.to_string() })
-        } else if let Some((name, source)) = split_once(s, '%') {
-            Ok(RoleIdentifier::Local { name: name.to_string(), source: source.to_string() })
+        if let Some((name, source)) = split_once(s, '/') {
+            Ok(RoleIdentifier { name: name.to_string(), source: source.to_string() })
         } else {
             Err(RoleFromStrError::Invalid)
         }
@@ -214,21 +203,18 @@ impl TryFrom<String> for RoleIdentifier {
     type Error = RoleFromStrError;
 
     fn try_from(s: String) -> std::result::Result<Self, Self::Error> {
-        if let Some((name, location)) = split_once(&s, '@') {
-            let location = &location[1..];
-            Ok(RoleIdentifier::Remote { name: name.to_string(), location: location.to_string() })
-        } else if let Some((name, source)) = split_once(&s, '%') {
-            let source = &source[1..];
-            Ok(RoleIdentifier::Local { name: name.to_string(), source: source.to_string() })
-        } else {
-            Err(RoleFromStrError::Invalid)
-        }
+        <RoleIdentifier as std::str::FromStr>::from_str(&s)
+    }
+}
+impl Into<String> for RoleIdentifier {
+    fn into(self) -> String {
+        format!("{}", self)
     }
 }
 
 impl RoleIdentifier {
     pub fn local_from_str(source: String, name: String) -> Self {
-        RoleIdentifier::Local { name, source }
+        RoleIdentifier { name, source }
     }
 }
 
@@ -505,7 +491,7 @@ impl TryFrom<String> for PermRule {
     }
 }
 
-#[cfg(test_DISABLED)]
+#[cfg(test)]
 mod tests {
     use super::*;
 
@@ -532,23 +518,46 @@ mod tests {
         assert!(rule.match_perm(&perm));
     }
 
+    #[test]
+    fn format_and_read_compatible() {
+        use std::convert::TryInto;
+
+        let testdata = vec![
+            ("testrole", "testsource"),
+            ("", "norole"),
+            ("nosource", "")
+        ].into_iter().map(|(n,s)| (n.to_string(), s.to_string()));
+
+        for (name, source) in testdata {
+            let role = RoleIdentifier { name, source };
+
+            let fmt_string = format!("{}", &role);
+
+            println!("{:?} is formatted: {}", &role, &fmt_string);
+
+            let parsed: RoleIdentifier = fmt_string.try_into().unwrap();
+
+            println!("Which parses into {:?}", &parsed);
+
+            assert_eq!(role, parsed);
+        }
+    }
+
     #[test]
     fn load_examples_roles_test() {
         let mut roles = Role::load_file("examples/roles.toml")
             .expect("Couldn't load the example role defs. Does `examples/roles.toml` exist?");
 
         let expected = vec![
-            (RoleIdentifier::Local { name: "testrole".to_string(), source: "lmdb".to_string() },
+            (RoleIdentifier { name: "testrole".to_string(), source: "lmdb".to_string() },
             Role {
-                name: "Testrole".to_string(),
                 parents: vec![],
                 permissions: vec![
                     PermRule::Subtree(PermissionBuf::from_string("lab.test".to_string()))
                 ],
             }),
-            (RoleIdentifier::Local { name: "somerole".to_string(), source: "lmdb".to_string() },
+            (RoleIdentifier { name: "somerole".to_string(), source: "lmdb".to_string() },
             Role {
-                name: "Somerole".to_string(),
                 parents: vec![
                     RoleIdentifier::local_from_str("lmdb".to_string(), "testparent".to_string()),
                 ],
@@ -556,9 +565,8 @@ mod tests {
                     PermRule::Base(PermissionBuf::from_string("lab.some.admin".to_string()))
                 ],
             }),
-            (RoleIdentifier::Local { name: "testparent".to_string(), source: "lmdb".to_string() },
+            (RoleIdentifier { name: "testparent".to_string(), source: "lmdb".to_string() },
             Role {
-                name: "Testparent".to_string(),
                 parents: vec![],
                 permissions: vec![
                     PermRule::Base(PermissionBuf::from_string("lab.some.write".to_string())),
diff --git a/src/db/access/internal.rs b/src/db/access/internal.rs
index 1f8213b..f149c3f 100644
--- a/src/db/access/internal.rs
+++ b/src/db/access/internal.rs
@@ -77,6 +77,7 @@ impl Internal {
 
     pub fn _get_role<'txn, T: Transaction>(&self, txn: &'txn T, role_id: &RoleIdentifier) -> Result<Option<Role>> {
         let string = format!("{}", role_id);
+        debug!(self.log, "Reading role '{}'", &string);
         match txn.get(self.roledb, &string.as_bytes()) {
             Ok(bytes) => {
                 Ok(Some(flexbuffers::from_slice(bytes)?))
@@ -108,8 +109,10 @@ impl Internal {
                 Ok( (k,v) ) => {
                     let role_id_str = unsafe { std::str::from_utf8_unchecked(k) };
                     let role_id = role_id_str.parse::<RoleIdentifier>().unwrap();
-                    let role = flexbuffers::from_slice(v)?;
-                    vec.push((role_id, role));
+                    match flexbuffers::from_slice(v) {
+                        Ok(role) => vec.push((role_id, role)),
+                        Err(e) => error!(self.log, "Bad format for roleid {}: {}", role_id, e),
+                    }
                 },
                 Err(e) => return Err(e.into()),
             }