Index: libabac/abac_graph.c
===================================================================
--- libabac/abac_graph.c	(revision 675cbea0622153b318ae6108ea93f82b4836e994)
+++ libabac/abac_graph.c	(revision 342e28fe01e337ed4bef82e454ff69e7c9a80067)
@@ -113,4 +113,8 @@
     abac_role_t *head = abac_credential_head(cred);
     abac_role_t *tail = abac_credential_tail(cred);
+
+    // TODO: handle intersections properly
+    if (tail == NULL)
+        return 0;
 
     // a valid credential must have a role for the head
Index: libabac/abac_verifier.c
===================================================================
--- libabac/abac_verifier.c	(revision 675cbea0622153b318ae6108ea93f82b4836e994)
+++ libabac/abac_verifier.c	(revision 342e28fe01e337ed4bef82e454ff69e7c9a80067)
@@ -8,4 +8,5 @@
 #include "abac_verifier.h"
 
+#include "abac_list.h"
 #include "abac_util.h"
 
@@ -20,4 +21,5 @@
     abac_role_t *head;
     abac_role_t *tail;
+    abac_list_t *prereqs; // an intersecton has prereqs, not a tail
     certificate_t *cert;
     certificate_t *issuer;
@@ -162,4 +164,23 @@
 
 /**
+ * Split a string based on the given delimiter.
+ */
+static void _split(char *string, char *delim, char **ret, int *num) {
+    int len = strlen(delim);
+    char *start = string;
+    int count = 0;
+
+    // split the string by the delim
+    while ((start = strstr(string, delim)) != NULL) {
+        *start = 0;
+        ret[count++] = string;
+        string = start + len;
+    }
+    ret[count++] = string;
+
+    *num = count;
+}
+
+/**
  * Load an attribute cert.
  * Returns true only if the certificate is valid and is issued by the proper
@@ -171,5 +192,6 @@
     abac_role_t *tail_role = NULL;
     abac_id_cert_t *issuer;
-    int ret;
+    abac_list_t *prereqs = NULL;
+    int ret, i;
 
     // get the attr
@@ -188,6 +210,6 @@
 
     // split into head/tail parts
-    char head[256], tail[256];
-    ret = sscanf(attr_string, "%255s <- %255s", head, tail);
+    char *head_tail[2];
+    _split(attr_string, " <- ", head_tail, &ret);
     if (ret != 2) {
         ret = ABAC_CERT_INVALID;
@@ -196,5 +218,5 @@
 
     // must be a role
-    head_role = abac_role_from_string(head);
+    head_role = abac_role_from_string(head_tail[0]);
     if (head_role == NULL) goto error;
     if (!abac_role_is_role(head_role)) {
@@ -203,10 +225,27 @@
     }
 
-    // make sure the tail role is valid
-    tail_role = abac_role_from_string(tail);
-    if (tail_role == NULL) {
-        ret = ABAC_CERT_INVALID;
-        goto error;
-    }
+    // split the tail (in case of an intersection num_tails > 1)
+    char *tails[256];
+    int num_tails;
+    _split(head_tail[1], " & ", tails, &num_tails);
+
+    if (num_tails > 1)
+        prereqs = abac_list_new();
+
+    for (i = 0; i < num_tails; ++i) {
+        // make sure the tail role is valid
+        tail_role = abac_role_from_string(tails[i]);
+        if (tail_role == NULL) {
+            ret = ABAC_CERT_INVALID;
+            goto error;
+        }
+
+        // add to the list if intersection
+        if (num_tails > 1)
+            abac_list_add(prereqs, tail_role);
+    }
+
+    if (num_tails > 1)
+        tail_role = NULL;
 
     // get the issuer based on keyid
@@ -229,4 +268,5 @@
     cred->head = head_role;
     cred->tail = tail_role;
+    cred->prereqs = prereqs;
     cred->cert = cert;
     cred->issuer = issuer->cert->get_ref(issuer->cert);
@@ -244,4 +284,12 @@
     if (head_role != NULL) abac_role_free(head_role);
     if (tail_role != NULL) abac_role_free(tail_role);
+
+    // free all the tail roles
+    if (prereqs != NULL) {
+        abac_list_foreach(prereqs, tail_role,
+            abac_role_free(tail_role);
+        );
+        abac_list_free(prereqs);
+    }
 
     return ret;
@@ -293,4 +341,11 @@
 
 /**
+ * Return the prereqs. Non-NULL iff intersection.
+ */
+abac_list_t *abac_credential_prereqs(abac_credential_t *cred) {
+    return cred->prereqs;
+}
+
+/**
  * Return the encoding of the attribute cert.
  */
@@ -336,4 +391,12 @@
     cred->issuer->destroy(cred->issuer); // reference counted
 
+    if (cred->prereqs != NULL) {
+        abac_role_t *tail;
+        abac_list_foreach(cred->prereqs, tail,
+            abac_role_free(tail);
+        );
+        abac_list_free(cred->prereqs);
+    }
+
     free(cred);
 }
