Google Apps Directory API: Unofficial guide

about | archive


[ 2013-December-29 14:40 ]

With Mitro, customers can control access to passwords using their Google Apps users and groups. Unfortunately, the Google Apps Directory API documentation doesn't cover how some of the Google Apps features interact. I experimented using my Google Apps domain, so the other five people using this API don't have to.

Things everyone using the Directory API should know

Google Apps users: Use ids, not email addresses

Applications like Docs and Calendar identify users by their primary email address. However, users can have multiple addresses, through user aliases and domain aliases. Even worse, administrators can change a user's primary email address, or delete the account and re-use the address with a new account. This means email addresses are not permanent, and you must use the id to refer to a user, not their email address. Only when you are displaying a user in a human understandable way should you use the primary email address (and ideally also their name and user photo). You can get a photo from the thumbnailPhotoUrl property, which is easier than using the Users.photos API. If someone can select a user by email address, for example by typing an address in a "share with ..." dialog box, you should pull all the aliases from the aliases and nonEditableAliases lists, and match any of them.

Google Apps user names are case-insensitive (e.g. User@example.com and useR@example.com refer to the same inbox). However, the primary email address returned by Google can contain uppercase or lowercase letters (exactly as it is entered in the Google Apps control panel). Unlike Gmail, dots are treated as part of the user name (see character usage and limits).

Google Apps Groups

Unfortunately, Google Apps groups are really a list of email addresses, which means they are flexible but have some weird corner cases. When Google figures out that an email address points to a group or a Google Apps account, it "magically" matches that group member record to the user/group. However, because the group members are just a list of email addresses, groups can contain aliases, non-existent accounts, and external addresses.

Like user accounts, groups have a primary email address and aliases. It is not currently possible to change the group's primary email address through the UI. It may be possible through the API, but I haven't tried.

Google Apps user members

Group members that refer to a Google Apps account have "type": "USER" and an email address. If the email address resolves to a user account (considering all aliases and domains), then the id matches the user id from the domain list. The email address can be any of an account's aliases, and not necessarily the primary email address, so again: don't match members using email addresses. If the user is renamed or deleted the group entries are automatically renamed or updated as needed.

Group members

Groups have type="GROUP", and an email address. As with users, the address recorded here could be an alias, and not the primary address, so use the id to map it to the correct group.

Unknown email address members

Arbitrary email addresses can be added to a group. This address could be on a domain that is "owned" by this Google apps account (e.g. baduser@yourdomain.com), or an "external" domain. You can detect this case because the id will not match any user accounts. Each "unknown" email address is assigned a unique id that never seems to change. If the address is added to multiple groups, or if the address is deleted from all groups and re-added, it always has the same id (even if the address temporarily was used by a valid Google account). Google does not look at domain aliases when determining these ids. For example, if example.com is an alias for yourdomain.com, then baduser@yourdomain.com and baduser@example.com have different ids.

Magic "all users on domain" group member

When creating or editing a group, Google Apps provide the option to "include all users on domain" (although it actually means "all users in this Google Apps account"). This is represented as a group member with "type": "USER" but without an email address. The id for this special member is the same within a Google apps account. This means if you have two groups, even in different domains, and they both contain the "all users" member, those members have the same id. However, between two different Google Apps accounts, this entry has a unique id. Here is an example list members response for a group that only contains the "all users" member.

{
  "etag":"\"TS0gIST2no9N9ttbhzWWRxUMaA0/lzlc3TuUxJuzbopDgvL3sKplUbs\"",
  "kind":"admin#directory#members",
  "members":[
    {
      "etag":"\"TS0gIST2no9N9ttbhzWWRxUMaA0/qvsjOEJMITksOeL4U18n6AMhMB0\"",
      "id":"107973652483781029281",
      "kind":"admin#directory#member",
      "role":"MEMBER",
      "type":"USER"
    }
  ]
}

Deleting aliases

If you delete an email alias that was referenced as a group member, the group member's email address is updated to the account or group's primary address.

Changing primary addresses and accounts

When you change a user's primary address or delete the account, that account's group memberships are changed/deleted as needed.

Suspended users

Suspended users do not appear as group members in the API. Interestingly, the Google Apps admin console shows these users as "Member (suspended)", but that information does not appear to be available through the API.

Collisions with email address group members

Since groups can contain addresses that do not reference a user account, you can get collisions with new accounts, aliases, or renamed accounts. This means that adding an alias or renaming a user can cause them to become a member of a group. It also causes the id of the group member id to change (from the "unknown" address id to the id of the user account). This basically works the way I expect: if an existing group member email address now resolves to a user account, the id is updated to reference the account. This is potentially a strange case. If you look at group member ids, this looks like a member being removed and a new one added (that happens to have the same email address). If you look at the email address, it looks like nothing has changed. You should consider which of these is the right choice for your application.

I also temporarily observed a group with multiple aliases for a single user: I created a group with two members that did not exist: baduser@domain.com and baduser@alias.com. Since there is no user account, Google Apps adds these accounts as two separate members, with two separate ids, even though these domains are aliases. I then added baduser@domain.com as a user. This changed the id for baduser@domain.com to match the new user account, but left baduser@mitro.co unchanged, even though it delivers to the same account. Shortly after, the alias was automatically removed from the group, so hopefully most applications can just ignore this.