# KIM Selection Hints Overview

## Introduction

Most users belong to multiple organizations and thus need to authenticate to multiple Kerberos realms. Traditionally Kerberos sites solved this problem by setting up a cross-realm relationship, which allowed the user to use TGT credentials for their client identity in one realm to obtain credentials in another realm via cross-realm authentication. As a result users could acquire credentials for a single client identity and use them everywhere.

Setting up cross-realm requires that realms share a secret, so sites must coordinate with one another to set up a cross-realm relationship. In addition, sites must set up authorization policies for users from other realms. As Kerberos becomes increasingly wide-spread, many realms will not have cross-realm relationships, and users will need to manually obtain credentials for their client identity at each realm (eg: "user@BANK.COM", "user@UNIVERSITY.EDU", etc). As a result, users will often have multiple credentials caches, one for each client identity.

Unfortunately this presents a problem for applications which need to obtain service credentials. Which client identity should they use? Rather than having each application to manually search the cache collection, KIM provides a selection hints API for choosing the best client identity. This API is intended to simplify the process of choosing credentials and provide consistent behavior across all applications.

Searching the cache collection for credentials may be expensive if there are a large number of caches. If credentials for the client identity are expired or not present, KIM may also wish to prompt the user for new credentials for the appropriate client identity. As a result, applications might want to remember which client identity worked in the past and always request credentials using that identity.

## Creating KIM Selection Hints

A KIM selection hints object consists of an application identifier and one or more pieces of information about the service the client application will be contacting. The application identifier is used by user preferences to control how applications share cache entries. It is important to be consistent about what application identifier you provide. Java-style identifiers are recommended to avoid collisions.

## Selection Hint Search Behavior

When using selection hints to search for an appropriate client identity, KIM uses a consistent hint search order. This allows applications to specify potentially contradictory information without preventing KIM from locating a single ccache. In addition the selection hint search order may change, especially if more hints are added.

As a result, callers are encouraged to provide all relevant search hints, even if only a subset of those search hints are necessary to get reasonable behavior in the current implementation. Doing so will provide the most user-friendly selection experience.

Currently the search order looks like this:

- Service Identity The client identity which has obtained a service credential for this service identity.
- Server A client identity which has obtained a service credential for this server.
- Service Realm A client identity which has obtained a service credential for this realm.
- Service A client identity which has obtained a service credential for this service.
- Client Realm A client identity in this realm.
- User A client identity whose first component is this user string.

For example, if you specify a service identity and a credential for that identity already exists in the ccache collection, KIM may use that ccache, even if your user and client realm entries in the selection hints would lead it to choose a different ccache. If no credentials for the service identity exist then KIM will fall back on the user and realm hints.

Note:
  Due to performance and information exposure concerns, currently all searching is done by examining the cache collection. In the future the KIM may also make network requests as part of its search algorithm. For example it might check to see if the TGT credentials in each ccache can obtain credentials for the service identity specified by the selection hints.

## Selecting an Identity Using Selection Hints

Once you have provided search criteria for selecting an identity, use kim_selection_hints_get_identity() to obtain an identity object. You can then use kim_identity_get_string() to obtain a krb5 principal string for use with gss_import_name() and gss_acquire_cred(). Alternatively, you can use kim_ccache_create_from_client_identity() to obtain a ccache containing credentials for the identity.

Note:
  kim_selection_hints_get_identity() obtains an identity based on the current state of the selection hints object. If you change the selection hints object you must call kim_selection_hints_get_identity() again.

## Selection Hint Caching Behavior

In addition to using selection hints to search for an appropriate client identity, KIM can also use them to remember which client identity worked. KIM maintains a per-user cache mapping selection hints to identities so that applications do not have to maintain their own caches or present user interface for selecting which cache to use.

When kim_selection_hints_get_identity() is called KIM looks up in the cache and returns the identity which the selection hints map to. If there is not a preexisting cache entry for the selection hints then kim_selection_hints_get_identity() will search for an identity and prompt the user if it cannot find an appropriate one.

If the client identity returned by KIM authenticates and passes authorization checks, you should tell KIM to cache the identity by calling kim_selection_hints_remember_identity(). This will create a cache entry for the mapping between your selection hints and the identity so that subsequent calls to kim_selection_hints_get_identity() do not need to prompt the user.

If the client identity returned by KIM fails to authenticate or fails authorization checks, you must call kim_selection_hints_forget_identity() to remove any mapping that already exists. After this function is called, future calls to kim_selection_hints_get_identity() will search for an identity again. You may also wish to call this function if the user changes your application preferences such that the identity might be invalidated.

Note:
  It is very important that you call kim_selection_hints_forget_identity() if your application fails to successfully establish a connection with the server. Otherwise the user can get "stuck" using the same non-working identity if they chose the wrong one accidentally or if their identity information changes. Because only your application understands the authorization checksof the protocol it uses, KIM cannot tell whether or not the identity worked.

If you wish to search and prompt for an identity without using the cached mappings, you can turn off the cached mapping lookups using kim_selection_hints_set_remember_identity(). This is not recommended for most applications since it will result in a lot of unnecessary searching and prompting for identities.

Note:
  Because cache entries key off of selection hints, it is important to always specify the same hints when contacting a particular service. Otherwise KIM will not always find the cache entries.

## Selection Hint Prompting Behavior

If valid credentials for identity in the selection hints cache are unavailable or if no identity could be found using searching or caching when kim_selection_hints_get_identity() is called, KIM may present a GUI to ask the user to select an identity or acquire credentials for an identity.

Note:
  Because of the caching behavior described above the user will only be prompted to choose an identity when setting up the application or when their identity stops working.

In order to let the user know why Kerberos needs their assistance, KIM displays the name of the application which requested the identity selection. Unfortunately, some platforms do not provide a runtime mechanism for determining the name of the calling process. If your application runs on one of these platforms (or is cross-platform) you should provide a localized version of its name with the private function kim_library_set_application_name().

In many cases a single application may select different identities for different purposes. For example an email application might use different identities to check mail for different accounts. If your application has this property you may need to provide the user with a localized string describing how the identity will be used. You can specify this string with kim_selection_hints_get_explanation(). You can find out what string will be used with kim_selection_hints_set_explanation().

Since the user may choose to acquire credentials when selection an identity, KIM also provides kim_selection_hints_set_options() to set what credential acquisition options are used. kim_selection_hints_get_options() returns the options which will be used.

If you need to disable user interaction, use kim_selection_hints_set_allow_user_interaction(). Use kim_selection_hints_get_allow_user_interaction() to find out whether or not user interaction is enabled. User interaction is enabled by default.

See KIM Selection Hints Reference Documentation for information on specific APIs.