Changes between Initial Version and Version 1 of CommonFederationAPIv2


Ignore:
Timestamp:
03/12/14 13:33:50 (10 years ago)
Author:
tmitchel@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CommonFederationAPIv2

    v1 v1  
     1[[PageOutline(1-2, Table of Contents)]]
     2== GENI Federation API’s ==
     3Marshall Brinn, GPO
     4
     5API Version 2 
     6
     7Revised: November 13, 2013
     8
     9
     10== Introduction ==
     11
     12
     13
     14This document proposes a set of standard API’s that any GENI-compatible Federation should or may provide. The document describes what is required and what is optional in the calls and responses to these APIs.
     15
     16The GENI Software Architecture rests on the interaction between different entities:
     17
     18''' Aggregates ''' : Collections of resources managed and presented in accordance with the AM API
     19
     20''' Members ''' : Experimenters or other human consumers of aggregate resources
     21
     22''' Authorities ''' : Services that manage assertions about members and their permissions with respect to aggregate resources.
     23
     24There are two fundamental authority types in GENI:
     25
     26 * '' Member Authority '' [MA]: Manages and asserts attributes about particular members
     27 * '' Slice Authority '' [SA]: Manages slice objects and generates credentials for members with respect to slices.
     28
     29A '' Federation '' is a collection of Authorities and Aggregates that establish mutual trust and common policies to facilitate the sharing of resources among members. A Federation Registry is a software service representing a given Federation, providing lists of Slice Authorities, Member Authorities and aggregates associated with that federation, and providing a set of PKI certificates that any aggregate belonging to a given federation accepts as trust roots. The relationship of Federations to Federation Registries is 1:1.
     30
     31The Authorities of any given Federation are free to implement their own Authorization (AuthZ) scheme. The API’s allow for passing credentials to the calls, but an Authority may choose to allow or disallow calls using logic and policies that are internal to that Federation. There is no universal (cross-Federation) requirement for any particular policy regarding Authority AuthZ.
     32
     33Authorities are fundamentally independent of one another. The objects defined at one Authority are not necessarily entitled to any services provided by another Authority. Each aggregate may choose to trust or not trust any particular Authority. Likewise, any Authority may chose to trust or not trust any other Authority.  A Federation Registry may choose to advertise or not advertise any particular aggregate, regardless of whether that aggregate trusts the Authorities advertised by that Federation Registry. Similarly, a given Slice Authority or Member Authority may be advertised by a single Federation Registries or by multiple Federation Registries. Federation Registry API calls are unprotected. There is no notion of trust between Federation Registries or between Federation Registries and Authorities or Aggregates.
     34
     35This document describes the APIs of the Federation Registry as well as the MA and SA. It is expected that a well-behaved GENI-compatible tool will allow for interacting with any Federation Registry and Authority that implement the standard API’s described in this document.
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46== API General Properties ==
     47
     48The APIs described here share some common properties, which should be assumed for the rest of this document:
     49 * The wire-protocol is XML/RPC. It is thus language independent on both client and server side of the API calls.
     50 * Most calls are protected, running over SSL and thus requiring the caller to use its certificate and private key. Certain calls are unprotected and can be accessed with no requirement for a validated client-side certificate . Such calls will noted in the API documentation below.
     51 * Each call takes an ‘options’ argument, a dictionary allowing for passing specific non-standard/optional arguments
     52 * Each protected method takes a ‘credentials’ argument, a list of type/credential tuples that help the Federation Registry or Authority invoke whatever AuthZ logic it may choose. As noted above, the Federation Registry or Authority may choose to use or disregard these credentials. Unprotected methods do not take a ‘credentials’ argument.
     53 * Each Federation Registry or Authority provides a get_version method, which describes the version number of the API provided, credential types supported, supplementary object fields and other data for interpreting API call returns.
     54 * A Federation Registry or Authority is free to implement additional methods beyond those specified in this document.
     55 * The URN is the fundamental identifier in all Federation API’s. URN’s are globally unique at any given time, though not necessarily unique over time. Disambiguation for entities with the same URN over time may be provided by an optional UUID argument for certain API methods. The format of URN's is documented at http://groups.geni.net/geni/wiki/GeniApiIdentifiers.
     56
     57These API’s are provided in pseudo-code (i.e. language independent) format, with inputs and outputs (optional and required) described by comments, e.g.
     58
     59{{{
     60#!python
     61# Perform method fed_func
     62#
     63# Arguments:
     64#  argl : ...
     65#  credentials : list of {type : credential} tuples representing credentials
     66#     provided by caller to support AuthZ on method call.
     67#      [NB: This argument will be omitted in descriptions below. ]
     68#  options : … [ Recognized options: ….]
     69#
     70# Return:
     71#  E.g. a list of dictionaries with these fields mandatory (…)
     72#                                         and these fields optional (…)
     73def fed_func (arg1, arg2, credentials, options)
     74}}}
     75
     76
     77== API 'get_version' methods ==
     78
     79Different Federation Authorities will provide different sets of methods bundled into services. Further, they will manage different kinds of objects and support different details for these objects.
     80
     81Each Federation Registry or Authority API provides a ‘get_version’ method, which provides information to the caller (or a tool composing calls for a tool user) about versions and options supported by that API. The call takes no argument and is unguarded (anyone can call it). The return from the get_version call will be a dictionary including the following entries (by key):
     82 * VERSION: A string with the version number of the Federation API (e.g. “2”, the version for this document). Note: this is the version of the API not the version of the implementation. This field is mandatory for all services.
     83 * URN : The URN of the service being contacted. This field is mandatory for SA and MA services, optional for Federation Registry service.
     84 * IMPLEMENTATION: A dictionary of information of the implantation of the service: {"code_version" : code_version, "code_url" : code_url, "code_release_date" : code_release_date, "site_update_date" : site_update_date"}. Of these, code_version is of type STRING, code_url is of type URL,  code_release_date and site_update_date are of format DATETIME. The format of the code_version string is implementation specific. This field is optional for services; in addition, all the sub-fields for the IMPLEMENTATION field are optional.
     85 * SERVICES: The list of names of services the given URL supports. This field is optional (with default being the default service for that authority, i.e. SERVICE for Federation Registry, SLICE for Slice Authority, MEMBER for MemberAuthority). 
     86 * CREDENTIAL_TYPES: A list of recognized credential types (e.g. [geni_sfa, geni_abac]) and list of supported credential versions on protected API methods.  Format is analogous to that in the AM API: a list of {"type": cred_type, "version" : cred_version} dictionaries of all supported credential types and versions. ''[Required for Authorities only]''
     87 * ROLES : A list of recognized roles for slice/project membership (required only for those Slice Authorities supporting membership). The same set of roles refers to both slice and project membership at a given SA.
     88 * SERVICE_TYPES. A list of service types provided by the Federation Registry ''[Required for Federation Registry only]''
     89 * API_VERSIONS A dictionary of different peer implementation of different version of the same service. Modeled on the Aggregate Manager API, the format of this field is {version1 : url1, version2 : url2, …}. This field is required for all services. Note that the 'self' version (the version of the service being queried) is required to be included in this dictionary and should be consistent with the "VERSION" field above. The URL's in this field
     90 * FIELDS: A dictionary of object field names (i.e. in additional to the required fields) and associated attributes including:
     91     * “OBJECT” provides the object type to which the field belongs. The field is optional for fields of the default authority object (i.e. SLICE for Slice Authority, MEMBER for Member Authority, SERVICE for Federation Registry) but mandatory for all other fields.
     92     * “TYPE” may be one of “URN”, “UID”, “STRING”, “DATETIME”, “EMAIL”, “KEY”,“BOOLEAN”, “CREDENTIAL”, “CERTIFICATE”. [NB. This set of types subject to change. See Appendix for more information on these data types.] This field is mandatory for any field listed.
     93     * “CREATE” attributes may be specified as “REQUIRED”, “ALLOWED” or “NOT ALLOWED” (default = “NOT ALLOWED”). These indicate whether the given supplementary field is required, allowed or prohibited in create calls. This attribute is optional for listed fields.
     94     * "MATCH" attributes may be specified as booleans TRUE or FALSE (default = TRUE). These indicate whether a given field may be specified in an match option of a lookup call. This attribute is optional for listed fields.
     95     * “UPDATE” attributes may be specified as booleans TRUE or FALSE (default = FALSE). These indicate whether the given field may be specified in an update call. This attribute is optional for listed fields.
     96     * “PROTECT” attributes may be labeled as “PUBLIC”, “PRIVATE” or “IDENTIFYING”. These are for the Member Authority only to differentiate between public, identifying and private data fields on members. The default, if not provided, is "PUBLIC", and thus this attribute is optional.
     97
     98The FIELDS element of the get_version should contain all supplementary (non-mandatory) field objects supported by a given service. Additionally, it may contain mandatory field objects for which the default semantics (for "CREATE", "MATCH", "UPDATE", "PROTECT") should be overridden. Specifically, any values specified override the default values and any values unspecified are defined to be the defaults for that object/field in this document. The FIELDS element is thus optional for all services.
     99
     100The set of ROLES may vary across Slice Authorities based on local policy. However, the following roles should be defined at any Slice Authority:
     101
     102|| '''Role''' || '''Contex'''' || '''Description''' ||
     103|| LEAD || PROJECT || May change project membership and create slices within a given project ||
     104|| || SLICE || May change slice membership  and perform operations on a given slice||
     105|| MEMBER || PROJECT || May create slices within given project ||
     106|| || SLICE || May perform operations on given slice ||
     107
     108Supplementary field names should be placed in a distinct namespace by a prefix unique to that federation, and starting with an underscore (e.g. _GENI_,  _OFELIA_ , _FED4FIRE_ or _PROTOGENI_ etc.).
     109
     110The API_VERSIONS field of the get_version should contain a dictionary specifying different URL's implementing different versions of the same service. The URL's provided should be absolute, containing publicly accessible addresses. This information may be used by the Federation Registry to provide SERVICE_PEERS information described below. An example API_VERSIONS field from a get_version call:
     111{{{
     112    "API_VERSIONS": {
     113         "1" : "https://example.com/xmlrpc/sa/1",
     114         "2" : "https://example.com/xmlrpc/sa/2"
     115      }   
     116}}}
     117
     118The return from the get_version call will be used to construct and validate options to Federation Registry and Authority API calls, as described in subsequent sections.
     119
     120The get_version method at any service has the following signature:
     121{{{
     122#!python
     123# Return information about version and options
     124#   (e.g. filter, query, credential types) accepted by this service
     125#
     126# Arguments: None
     127#
     128# Return:
     129#     get_version structure information as described above
     130def get_version()
     131}}}
     132
     133
     134The following page provides some example returns from different get_version calls.
     135
     136== Example get_version returns: ==
     137
     138The following is an example of a return from a get_version for an SA. The responses are all dictionaries via XMLRPC into the native implementation. They are shown here in JSON-like syntax:
     139
     140{
     141
     142“VERSION”: “2”,
     143
     144"URN" : urn:publicid:IDN+example.com+authority+sa",
     145
     146“SERVICES”: [“SLICE”, “PROJECT”, “SLICE_MEMBER”, “PROJECT_MEMBER”],
     147
     148"OBJECTS": [ "PROJECT" ],
     149
     150“CREDENTIAL_TYPES”: [{"type" : "geni_sfa", version" : 2}, {"type" : "geni_sfa", "version" : "3"}, {"type" : "geni_abac", "version" : "1"}]
     151
     152“ROLES” : [“LEAD”, “ADMIN”, “MEMBER”, “AUDITOR”, “OPERATOR” ],
     153
     154“FIELDS”: {
     155     
     156     "_GENI_PROJECT_UID": {"TYPE" : "UID", "UPDATE" : FALSE},
     157
     158     “_GENI_SLICE_EMAIL”: {“TYPE”: “EMAIL”, “CREATE”: “REQUIRED”, “UPDATE”: TRUE},
     159     
     160     “_GENI_PROJECT_EMAIL”: {“TYPE”: “EMAIL”, “CREATE”: “REQUIRED”, “UPDATE”: TRUE, “OBJECT”: “PROJECT”}
     161       
     162      }
     163
     164}
     165
     166The following is an example of a return from a get_version for an MA, provided in JSON-like syntax:
     167
     168{
     169
     170      “VERSION”: “2”,
     171
     172       "URN" : urn:publicid:IDN+example.com+authority+ma",
     173
     174      “CREDENTIAL_TYPES”:  [{"type" : "geni_sfa", version" : 2}, {"type" : "geni_sfa", "version" : "3"}, {"type" : "geni_abac", "version" : "1"}]
     175
     176      "SERVICES": ["MEMBER", "KEY"],
     177
     178      "OBJECTS": [ "KEY" ],
     179
     180      “FIELDS”: {
     181   
     182       “MEMBER_DISPLAYNAME”: {“TYPE”: “STRING”, “CREATE”: “ALLOWED”, “UPDATE”,
     183
     184TRUE, “PROTECT”: “IDENTIFYING”},
     185
     186      “MEMBER_AFFILIATION”: {“TYPE”: “STRING”, “CREATE”: “ALLOWED”, “UPDATE”:
     187
     188TRUE, “PROTECT”: “IDENTIFTYING”},
     189
     190      “MEMBER_SSL_PUBLIC_KEY”: {“TYPE”: “SSL_KEY”},
     191
     192      “MEMBER_SSL_PRIVATE_KEY”: {“TYPE”: “SSL_KEY”, “PROTECT”: “PRIVATE”},
     193
     194      “MEMBER_SSH_PUBLIC_KEY”: {“TYPE”: “SSH_KEY”},
     195
     196      “MEMBER_SSH_PRIVATE_KEY”: {“TYPE”: “SSH_KEY”, “PROTECT”: “PRIVATE”},
     197
     198      “MEMBER_ENABLED”: {“TYPE”: “BOOLEAN”, “UPDATE”: TRUE}
     199    }
     200
     201}
     202
     203The following is an example of a return from a get_version from a Federation Registry, provided in JSON-like syntax:
     204
     205{
     206      “VERSION”: “2”,
     207
     208      "URN" : urn:publicid:IDN+example.com+authority+fr",
     209
     210      "SERVICE_TYPES" : ["SLICE_AUTHORITY", "MEMBER_AUTHORITY", "AGGREGATE_MANAGER"],
     211
     212      “FIELDS”: {
     213
     214              “SERVICE_PROVIDER”: {“TYPE”: “STRING”}}
     215
     216     }
     217
     218}
     219
     220== API Error Handing ==
     221
     222All method calls return a tuple [code, value, output]. What is described as ‘Return’ in the API’s described below is the ‘value’ of this tuple in case of a successful execution. ‘Code’ is the error code returned and ‘output’ is the returned text (e.g. descriptive error message).
     223
     224Each Federation Registry and Authority is free to define and return its own specific error codes. However we suggest the following essential set of error codes to report on generic conditions:
     225
     226|| ''' CODE_NAME ''' || ''' CODE_VALUE ''' || ''' DESCRIPTION ''' ||
     227|| NONE || 0 || No error encountered – the return value is a successful result. An empty list form a query should be interpreted as ‘nothing found matching criteria’. ||
     228|| AUTHENTICATION_ERROR || 1 || The invoking tool or member did not provide appropriate credentials indicating that they are known to the Federation or that they possessed the private key of the entity they claimed to be ||
     229|| AUTHORIZATION_ERROR || 2 || The invoking tool or member does not have the authority to invoke the given call with the given arguments ||
     230|| ARGUMENT_ERROR || 3 || The arguments provided to the call were mal-formed or mutually inconsistent. ||
     231|| DATABASE_ERROR || 4 || An error from the underlying database was returned. (More info should be provided in the ‘output’ return value] ||
     232|| DUPLICATE_ERROR || 5 || An error indicating attempt to create an object that already exists ||
     233|| NOT_IMPLEMENTED_ERROR || 100 || The given method is not implemented on the server. ||
     234|| SERVER_ERROR || 101 || An error in the client/server connection ||
     235
     236== Standard API Method ==
     237
     238Each Federation Registry and Authority manages the state of or access to objects. There are some standard methods that apply to standard operations on objects of specific types. All services support the following API's for the object types that are required or provided in get_version.
     239
     240{{{
     241#!python
     242# Creates a new instance of the given object with a ‘fields’ option
     243# specifying particular field values that are to be associated with the object.
     244# These may only include those fields specified as ‘ALLOWED or ‘REQUIRED’
     245# in the ‘Creation’ column of the object descriptions below
     246# or in the “CREATE’ key in the supplemental fields in the
     247# get_version specification for that object.
     248# If successful, the call returns a dictionary of the fields
     249# associated with the newly created object.
     250#
     251#
     252# Arguments:
     253#
     254#    type : type of object to be created
     255#   options:
     256#       'fields', a dictionary field/value pairs for object to be created
     257#
     258# Return:
     259#   Dictionary of object-type specific field/value pairs for created object
     260#
     261#
     262def create(type, credentials, options)
     263}}}
     264
     265{{{
     266#!python
     267# Updates an object instance specified by URN with a ‘fields’ option
     268#  specifying the particular fields to update.
     269# Only a single object can be updated from a single update call.
     270# The fields may include those specified as ‘Yes’ in the ‘Update’ column
     271# of the object descriptions below, or ’TRUE’ in the ‘UPDATE’ key in the
     272# supplemental fields provided by the get_version call.
     273# Note: There may be more than one entity of a given URN at an authority,
     274# but only one ‘live’ one (any other is archived and cannot be updated).
     275#
     276# Arguments:
     277#   type: type of object to be updated
     278#   urn: URN of object to update
     279#     (Note: this may be a non-URN-formatted unique identifier e.g. in the case of keys)
     280#   options: Contains ‘fields’ key referring dictionary of
     281#        name/value pairs to update
     282#
     283# Return: None
     284#
     285def update(type, urn, credentials, options)
     286}}}
     287
     288{{{
     289#!python
     290# Deletes an object instance specified by URN
     291# Only a single object can be deleted from a single delete call.
     292# Note: not all objects can be deleted. In general, it is a matter
     293#     of authority policy.
     294#
     295# Arguments:
     296#   type: type of object to be deleted
     297#   urn: URN of object to delete
     298#     (Note: this may be a non-URN-formatted unique identifier e.g. in the case of keys)
     299#
     300# Return: None
     301#
     302def delete(type, urn, credentials, options)
     303}}}
     304
     305{{{
     306#!python
     307# Lookup requested details for objects matching ‘match’ options.
     308# This call takes a set of ‘match’ criteria provided in the ‘options’ field,
     309# and returns a dictionary of dictionaries of object attributes
     310# keyed by object URN matching these criteria.
     311# If a ‘filter’ option is provided, only those attributes listed in the ‘filter’
     312# options are returned.
     313# The requirements on match criteria supported by a given service
     314# are service-specific; however it is recommended that policies
     315# restrict lookup calls to requests that are bounded
     316# to particular sets of explicitly listed objects (and not open-ended queries).
     317#
     318# See additional details on the lookup method in the document section below.
     319#
     320#
     321# Arguments:
     322#    type: type of objects for which details are being requested
     323#    options: What details to provide (filter options)
     324#            for which objects (match options)
     325#
     326# Return: List of dictionaries (indexed by object URN) with field/value pairs
     327#   for each returned object
     328#
     329def lookup (type, credentials, options)
     330}}}
     331
     332Some additional details on the lookup call:
     333
     334The options argument to the lookup call is a dictionary. It contains an entry with key ‘match’ that contains a dictionary of name/value pairs. The names are of fields listed in the get_version for that object. The values are values for those fields to be matched. The semantics of the match is to be an “AND” (all fields must match).
     335
     336The value in the dictionary of a ‘match’ option can be a list of scalars, indicating an “OR”. For example, a list of URNs provided to the SLICE_URN key would match any slice with any of the listed URNs.
     337
     338The options argument may include an additional dictionary keyed “filter” which is a list of fields associated with that object type (again, as specified in the get_version entry for that object). No “filter” provided means all fields are to be returned; a 'filter' provided with an empty list returns an empty set of fields (i.e. a dictionary of URN's pointing to empty dictionaries).
     339
     340The return of the call will be a dictionary of dictionaries, one per matching object indexed by URN, of fields matching the filter criteria. If the query found no matches, an empty dictionary is returned (i.e. no error is reported, assuming no other error was encountered in processing).
     341
     342If a lookup method call requests information in the 'match' criteria about objects whose disclosure is prohibited to the requester by policy, the call should result in an authorization error. If the 'filter' criteria requests fields whose disclosure is prohibited to the requestor by policy, the method must not return the specific data fields. Rather, it should return a dictionary with no entry for the prohibited fields. E.g. {"urn_1" : {"PUBLIC_KEY" : public_key_1, "PRIVATE_KEY" : private_key_1}, "urn_2" : {"PUBLIC_KEY" : public_key_2}}
     343
     344
     345== API Method Examples: ==
     346
     347A Member Authority (MA) manages information about member objects. The MA method lookup(type="MEMBER") could take an options argument such as
     348
     349{
     350
     351      "match”: {“MEMBER_LASTNAME”: “BROWN”},
     352     
     353      "filter”: [“MEMBER_EMAIL”, “MEMBER_FIRSTNAME”]
     354
     355Such a call would find any member with last name Brown and return a dictionary keyed by the member URN containing a dictionary with their email, and first name.
     356
     357''' { '''
     358
     359      “urn:publicid:IDN+mych+user+abrown” :
     360     
     361            {“MEMBER_EMAIL”: abrown@williams.edu,
     362           
     363            “MEMBER_FIRSTNAME”: “Arlene”},
     364     
     365      “urn:publicid:IDN+mych+user+mbrown” :
     366
     367            {“MEMBER_EMAIL”: mbrown@umass.edu,
     368
     369            “MEMBER_FIRSTNAME”: “Michael”},
     370
     371      “urn:publicid:IDN+mych+user+sbrown” :
     372
     373            {“MEMBER_EMAIL”: sbrown@stanford.edu,
     374
     375            “MEMBER_FIRSTNAME”: “Sam”}
     376
     377}
     378
     379A Slice Authority (SA) manages information about slice objects. The SA method update(type="SLICE") could take the following options argument to change the slice description and extend the slice expiration:
     380
     381{
     382
     383      “fields” : { “SLICE_DESCRIPTION”: “Updated Description”,
     384
     385                 “SLICE_EXPIRATION”: “2013-07-29T13:15:30Z” } 
     386
     387}
     388
     389An example of lookup(type="SLICE)" at an SA that wanted to retrieve the slice names for a list of slice URNs could specify options:
     390
     391{
     392 “match”: {
     393
     394      “SLICE_URN”: [
     395
     396             “urn:publicid+IDN+this_sa:myproject+slice+slice1”,
     397
     398             “urn:publicid+IDN+this_sa:myproject+slice+slice2”,
     399
     400             “urn:publicid+IDN+this_sa:myproject+slice+slice3”
     401
     402       ]},
     403
     404 “filter”: [“SLICE_NAME”]
     405
     406}
     407 
     408
     409== API Method Examples (cont.): ==
     410
     411An example of create(type="SLICE") call would specify required options e.g.:
     412
     413{
     414 
     415      ‘fields’ : {
     416
     417            “SLICE_NAME”: “TEST_SLICE”,
     418           
     419            “SLICE_DESCRIPTION”: “My Test Slice”,
     420
     421            “SLICE_EMAIL”: myemail@geni.net,
     422
     423            “SLICE_PROJECT_URN”: “urn:publicid+IDN+this_sa+project+myproject”
     424
     425       }
     426
     427}
     428
     429and receive a return dictionary looking like:
     430
     431{
     432
     433       “SLICE_URN”: “urn:publicid+IDN+this.sa+slice+TESTSLICE”,
     434
     435       “SLICE_UID”: “…”,
     436
     437       “SLICE_NAME”: “TESTSLICE”,
     438
     439       “SLICE_CREDENTIAL”: “.....”,
     440
     441       “SLICE_DESCRIPTION”: “My Test Slice”,
     442
     443       “SLICE_PROJECT_URN”: “urn:publicid+IDN+this_sa+project+myproject”,
     444
     445       “SLICE_EXPIRATION”: “2013-08-29T13:15:30Z”,
     446
     447       “SLICE_EXPIRED”: “FALSE”,
     448
     449       “SLICE_CREATION”: “2013-07-29T13:15:30Z”,
     450
     451       “SLICE_EMAIL”: myemail@geni.net
     452
     453}
     454
     455== API Authentication ==
     456
     457This document suggests that the Authentication required for the Federation APIs is implicit in the SSL protocol: the invoker of the call must have its cert and private key to have a valid SSL connection. Moreover, the cert must be signed by a member of the trust chain recognized by the Federation.
     458
     459== Support for Speaks-for API Invocations ==
     460
     461Best practices dictate that individuals should speak as themselves: that is, the entity on the other side of an SSL connection is the one referred to by the certificate on the connection. Obviously, people typically use tools or software interfaces to create these connections. When a tool is acting directly on a user’s desktop using the user’s key and cert with the user’s explicit permission, it may be acceptable to consider the tool as speaking as the user. But for many tools, the tool is acting on behalf of the user in invoking Federation or AM API calls. In this case, it is important for the tool to not speak as the user but to speak for the user, and to have the service to whom the tool is speaking handle the authorization and accountability of this request accordingly.
     462
     463Accordingly, a Federation Registry and associated Authorities should support speaks-for API transactions. These API transactions use the same signatures as the calls described in this document, with these enhancements:
     464
     465- A 'speaking_for' option containing the URN of the user being spoken for
     466
     467- A speaks-for credential in the list of credentials: a statement signed by the user indicating that the tool has the right to speak for the user, possibly limited to a particular scope (e.g. slice, project, API call, time window).
     468
     469The service call is then required to determine if the call is being made in a speaks-for context or not (that is, the ‘speaking_for’ option provided). If so, the call must determine if the tool is allowed to speak for the user by checking for the presence of a valid speaks-for credential and the spoken-for user’s cert. If so, the call should validate if the user is authorized to take the proposed API action. If so, the action is taken and accounted to the user, with identity of the speaking_for tool logged. If the call is ‘speaks-for’ but any of these additional criteria are not met, the call should fail with an authorization error. If the call is not a ‘speaks-for’, then the normal authorization is performed based on the identity (certificate) provided with the SSL connection.
     470
     471Aggregates are also encouraged to support speaks-for authentication and authorization, but this is an aggregate-internal policy and implementation decision, and outside the scope of this document.
     472
     473== Federation Registry API ==
     474
     475The Federation Registry provides a list of Slice Authorities, Member Authorities and Aggregates associated with a given Federation. The URL for accessing these methods (i.e. the URL of the Federation Registry) is to be provided out-of-band (i.e. there is no global service for gaining access to Federation Registry addressees).
     476
     477All Federation Registry calls are unprotected; they have no requirement for passing a client-side cert or validating any client-cert cert that is passed.
     478
     479The Federation Registry implements the SERVICE service and supports the SERVICE object.
     480
     481Services have a particular type that indicates the kind of service it represents. The full list of supported services should be provided by a TYPES key in the Federation Registry get_version call, for example:
     482
     483{{{
     484    {
     485       …
     486       "SERVICE_TYPES" : ["SLICE_AUTHORITY", "MEMBER_AUTHORITY",
     487                      "AGGREGATE_MANAGER", ...]
     488       …
     489    }
     490}}}
     491
     492This table contains a set of ''example'' services types (of which only SLICE_AUTHORITY, MEMBER_AUTHORITY and AGGREGATE_MANAGER are required for any given federation):
     493
     494|| ''' Service ''' || ''' Description ''' ||
     495|| SLICE_AUTHORITY || An instance of the Slice Authority Federation service described in this document ||
     496|| MEMBER_AUTHORITY || An instance of the Member Authority Federation service described in this document ||
     497|| AGGREGATE_MANAGER || An instance of an Aggregate Manager satisfying the Aggregate Manager API ||
     498|| STITCHING_COMPUTATION_SERVICE || A topology service for supporting cross-aggregate stitching ||
     499|| CREDENTIAL_STORE || A service holding credentials for the federation, typically for supporting federation authentication services ||
     500|| LOGGING_SERVICE || A service to support federation-level event logging ||
     501
     502The following table describes the standard fields for services (aggregates and authorities) provided by Federation Registry API calls. (The 'Required' column indicates whether the field must be present for a valid service, 'match' indicates whether the field can be used in a lookup match criterion):
     503
     504
     505|| ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Required ''' || ''' Match ''' ||
     506|| SERVICE_URN || URN || URN of given service || Yes || Yes ||
     507|| SERVICE_URL ||URL || URL by which to contact the service || Yes || Yes ||
     508|| SERVICE_TYPE || STRING || Name of service type (from Federation Registry get_version.TYPES) || Yes || Yes ||
     509|| SERVICE_CERT || Certificate || Public certificate of service || No || No ||
     510|| SERVICE_NAME || String || Short name of service || Yes || No ||
     511|| SERVICE_DESCRIPTION || String || Descriptive name of service || No || No ||
     512|| SERVICE_PEERS || List of Dictionaries || URLs and version info for other running version of same service (see below) || No || No ||
     513
     514The SERVICE_PEERS field is similar to that in the AM API: a list of {version", 'url'} dictionaries for other supported peer services of different versions.
     515It is provided to allow a user/tool to determine which URL to contact without needing to poll the get_version call across a set of services.
     516The current service URL (provided in the SERVICE_URL field) should always be included in the SERVICE_PEERS.
     517The information provided by SERVICE peers should be consistent with that provided by the API_VERSIONS field from the get_version call to these specific services.
     518An example would be as follows:
     519{{{
     520[
     521{'version' : '1', 'url' : 'https://example.com/xmlrpc/v1'},
     522{'version' : '2', 'url' : 'https://example.com/xmlrpc/v2'},
     523]
     524
     525}}}
     526
     527The Federation Registry API supports these standard API methods for type="SERVICE":
     528
     529|| ''' Method ''' || ''' Description ''' ||
     530|| lookup || lookup services matching given match criteria. ||
     531
     532Note that even though the Federation Registry API does not require authentication and thus no client certificates, the API uses the common API signatures for all 'lookup' methods and thus takes a list of credentials. This list, however, should be empty and ignored by the implementation.
     533
     534Additionally, the Federation Registry API supports the following methods:
     535
     536{{{
     537#!python
     538# Return list of trust roots (certificates) associated with this Federation.
     539#
     540# Often this is a concatenatation of the trust roots of the included authorities.
     541# Note: Some of this information can be retrieved by
     542#   lookup(fields={"SERVICE_CERT"})
     543# However certificates of federation-level certs, certificate authorities or other
     544# non-service certificate signers can only be retrieved through this call.
     545#
     546# Arguments:
     547#   None
     548#
     549# Return:
     550#   List of certificates representing trust roots of this Federation.
     551def get_trust_roots()
     552}}}
     553
     554{{{
     555#!python
     556# Lookup the authorities for a given URNs
     557#
     558# There should be at most one (potentially none) per URN.
     559#
     560# This requires extracting the authority from the URN and then looking up the authority in the Federation Registry's set of services.
     561#
     562# Arguments:
     563#   urns: URNs of entities for which the authority is requested
     564#
     565# Return:
     566#   List of dictionaries {urn : url} mapping URLs of Authorities to given URN's
     567def lookup_authorities_for_urns(urns)
     568}}}
     569
     570The ''lookup_authorities_for_urns'' method maps object URN's to authority URN's. Note that the transformation from the URN's of objects (e.g. slice, project, member) to the URN's of their authority is a simple one, for example:
     571
     572|| '''Type''' || '''Object URN''' || '''Authority URN''' ||
     573|| Slice || urn:publicid:IDN+sa_name+slice+slice_name || urn:publicid:IDN+sa_name+authority+sa ||
     574|| Member || urn:publicid:IDN+ma_name+user+user_name || urn:publicid:IDN+ma_name+authority+ma ||
     575
     576
     577== Slice Authority API ==
     578
     579The Slice Authority API provides services to manage slices and their associated permissions. To support its AuthZ policies, a particular SA may choose to manage objects and relationships such as projects and slice/project membership. The SA API is thus divided into a set of services, each of which consists of a set of methods. Of these, only the SLICE service is required, the others are optional. If an SA implements a given service, it should implement the entire service as specified. All available SA service methods are available from the same SA URL. The get_version method should indicate, in the ‘SERVICES’ tag, which services the given SA supports.
     580
     581All SA calls are protected; passing and validating a client-side cert is required.
     582
     583The following is a list of potential SA services.
     584
     585
     586|| ''' Service ''' || ''' Description ''' || ''' Required ''' || ''' Object ''' ||
     587|| SLICE || Managing generation, renewal of slice credentials and slice lookup services || YES || SLICE ||
     588|| SLICE_MEMBER ||Defining and managing roles of members with respect to slices || NO || ||
     589|| SLIVER_INFO || Providing information about what Aggregates have reported having slivers for a given slice. Non-authoritative/advisory || NO || SLIVER_INFO ||
     590|| PROJECT || Defining projects (groupings of slices) and project lookup services || NO || PROJECT ||
     591|| PROJECT_MEMBER || Defining and managing roles of members with respect to projects || NO || ||
     592
     593== Slice Service Methods ==
     594
     595The Slice Authority manages the creation of slices, which are containers for allocating resources. It provides credentials (called slice credentials) which aggregates may use to make authorization decisions about allocating resources to a particular user to a particular slice. These slice credentials are one of the fields that may be provided from the create_slice call or requested in the lookup_slices call.
     596
     597The credentials passed to SA Slice Service methods are SA-specific. But a common case is for a tool to want to pass additional information about a user, obtained from the MA, to the SA to allow the SA to make informed authorization decisions. These credentials may be in the form of an SFA-style User Credential or ABAC credential. Common useful information from the MA to the SA about users would be slice-independent (the SA should know all slice-specific information about users) information about roles and attributes of that user. Two conventional roles are:
     598 * PI: The user has a PI lead and is typically considered appropriate for creating projects or slices (if there are no projects)
     599 * ADMIN: The user has special 'admin' privileges and can perform operations not otherwise authorized.
     600
     601Note that renewal of slice expiration is handled in the update_slice call (with “SLICE_EXPIRATION” specified as the options key. The semantics of slice expiration is that slice expiration may only be extended, never reduced. Further restrictions (relative to project expiration or relative to slice creation, e.g.) are SA-specific.
     602
     603The following table contains required fields for slice objects and whether they are allowed in lookup ‘match’ criteria, required at creation or allowed at update:
     604
     605|| ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Creation ''' || ''' Update ''' ||
     606|| SLICE_URN || URN || URN of given slice || Yes || No || No ||
     607|| SLICE_UID ||UID || UID (unique within authority) of slice || Yes || No || No ||
     608|| SLICE_CREATION || DATETIME || Creation time of slice || No || No || No ||
     609|| SLICE_EXPIRATION || DATETIME || Expiration time of slice || No || Allowed || Yes ||
     610|| SLICE_EXPIRED || BOOLEAN || Whether slice has expired || Yes || No || No ||
     611|| SLICE_NAME || STRING || Short name of Slice|| No || Required || No ||
     612|| SLICE_DESCRIPTION || STRING || Description of Slice || No || Allowed || Yes ||
     613|| SLICE_PROJECT_URN || URN || URN of project to which slice is associated (if SA supports project) || Yes || Required (if SA supports project) || No ||
     614
     615To clarify the semantics of the SLICE_PROJECT_URN field: it is a required field for those SAs that support the PROJECT service (and in this context may be matched and is required at creation time, but not updatable). In SAs that do not support projects, the field is not meaningful and should not be supported.
     616
     617NB: SLICE_NAME must adhere to the restrictions for slice names in the Aggregate Manager (AM) API, namely that it must be <= 19 characters, only alphanumeric plus hyphen, no leading hyphen.
     618
     619The Slice Service supports these standard API methods for type="SLICE":
     620
     621|| ''' Method ''' || ''' Description ''' ||
     622|| create || Creates a  new slice with provided details  ||
     623|| update || Updates given slice ||
     624|| ~~delete~~ || Note: No SA should support slice deletion since there is no authoritative way to know that there aren't live slivers associated with that slice.  ||
     625|| lookup || lookup slices matching given match criteria subject to authorization restrictions. ||
     626
     627Additionally, the Slice service provides the following methods:
     628
     629{{{
     630#!python
     631# Provide list of credentials for the caller relative to the given slice.
     632# If the invocation is in a speaks-for context, the credentials will be for the
     633# ‘spoken-for’ member, not the invoking tool.
     634#
     635# For example, this call may return a standard SFA Slice Credential and some
     636# ABAC credentials indicating the role of the member with respect to the slice.
     637#
     638# Note: When creating an SFA-style Slice Credential, the following roles
     639# typically allow users to operate at known GENI-compatible
     640# aggregates: "*" (asterisk)  or the list of "refresh", "embed",
     641#    "bind", "control" "info".
     642#
     643# Arguments:
     644#   slice_urn: URN of slice for which to get member’s credentials
     645#   options: Potentially contains ‘speaking_for’ key indicating a speaks-for
     646#      invocation (with certificate of the accountable member
     647#      in the credentials argument)
     648
     649# Return:
     650#   List of credential in “CREDENTIALS” format, i.e. a list of credentials with
     651# type information suitable for passing to aggregates speaking AM API V3.
     652def get_credentials(slice_urn, credentials, options)
     653}}}
     654
     655== Slice Member Service Methods ==
     656
     657Slices may have a set of members associated with them in particular roles. Certain SA may have policies that require certain types of membership requirements (exactly one lead, never empty, no more than a certain number of members, etc.). To that end, we provide a single omnibus method for updating slice membership in a single transaction, allowing any authorization or assurance logic to be supported at a single point in SA implementations.
     658
     659The set of recognized role types (e.g. LEAD, ADMIN, MEMBER, OPERATOR, AUDITOR) are to be listed in the get_version for a given Slice Authority.
     660
     661The following methods are written generically (with type arguments) to support the Slice Member Service as well as the Project Member Service (below).
     662
     663{{{
     664#!python
     665# Modify object membership, adding, removing and changing roles of members
     666#    with respect to given object
     667#
     668# Arguments:
     669#   type: type of object for whom to lookup membership (
     670#       in the case of Slice Member Service, "SLICE",
     671#       in the case of Project Member Service, "PROJECT")
     672#   urn: URN of slice/project for which to modify membership
     673#   Options:
     674#       members_to_add: List of member_urn/role tuples for members to add to
     675#              slice/project of form
     676#                 {‘SLICE_MEMBER’ : member_urn, ‘SLICE_ROLE’ : role}
     677#                    (or 'PROJECT_MEMBER/PROJECT_ROLE
     678#                    for Project Member Service)
     679#       members_to_remove: List of member_urn of members to
     680#                remove from slice/project
     681#       members_to_change: List of member_urn/role tuples for
     682#                 members whose role
     683#                should change as specified for given slice/project of form
     684#                {‘SLICE_MEMBER’ : member_urn, ‘SLICE_ROLE’ : role}
     685#                (or 'PROJECT_MEMBER/PROJECT_ROLE for Project Member Service)
     686#
     687# Return:
     688#   None
     689def modify_membership(type, urn, credentials, options)
     690}}}
     691
     692{{{
     693#!python
     694# Lookup members of given object and their roles within that object
     695#
     696# Arguments:
     697#   type: type of object for whom to lookup membership
     698#          (in the case of Slice Member Service, "SLICE",
     699#           in the case of Project Member Service, "PROJECT")
     700#   urn: URN of object for which to provide current members and roles
     701#
     702# Return:
     703#    List of dictionaries of member_urn/role pairs
     704#       [{‘SLICE_MEMBER’: member_urn,
     705#        ‘SLICE_ROLE’: role }...]
     706#         (or PROJECT_MEMBER/PROJECT_ROLE
     707#          for Project Member Service)
     708#          where ‘role’ is a string of the role name.
     709def lookup_members(type, urn, credentials, options)
     710}}}
     711
     712{{{
     713#!python
     714# Lookup objects of given type for which the given member belongs
     715#
     716# Arguments:
     717#   Member_urn: The member for whom to find slices to which it belongs
     718#
     719# Return:
     720#    List of dictionary of urn/role pairs
     721#        [(‘SLICE_URN’ : slice_urn, ‘SLICE_ROLE’ : role} ...]
     722#        (or PROJECT_MEMBER/PROJECT_ROLE
     723#           for Project Member Service)
     724#        for each object to which a member belongs,
     725#        where role is a string of the role name
     726def lookup_for_member(type, member_urn, credentials, options)
     727}}}
     728
     729== Sliver Info Service Methods ==
     730
     731Sliver information is authoritatively held in aggregates: aggregates know which slivers are in which slices at that aggregate. As a convenience to tools, aggregates are encouraged to register with the SA which slices they have information about. In this way, tools can reference only certain aggregates and not all known aggregates to get a useful (if not authoritative) set of sliver details for a slice.
     732
     733It is expected that the sliver_info create, update and delete calls will be restricted to aggregates (in which case no speaks-for credential is required). That said, SAs may implement authorization policies of their choosing on these calls.
     734
     735The following table contains the required fields for sliver info objects and whether they are allowed in lookup 'match' criteria, required at creation or allowed at update:
     736
     737|| '''Name''' || '''Type''' || '''Description''' || '''Match''' || '''Creation''' || '''Update''' ||
     738|| SLIVER_INFO_SLICE_URN || URN || URN of slice for registered sliver || Yes || Required || No ||
     739|| SLIVER_INFO_URN || URN || URN of registered sliver || Yes || Required || No ||
     740|| SLIVER_INFO_AGGREGATE_URN || URN || URN of aggregate of registered sliver || Yes || Required || No ||
     741|| SLIVER_INFO_CREATOR_URN || URN || URN of member/tool that created the registered sliver || Yes || Required || No ||
     742|| SLIVER_INFO_EXPIRATION || DATETIME || Time of sliver expiration || No || Required || Yes ||
     743|| SLIVER_INFO_CREATION || DATETIME || Time of sliver creation || No || Allowed || No ||
     744
     745Note that the SLIVER_INFO_URN is the unique key for this data table (there may be multiple slices per aggregate or multiple aggregates per slice, but the sliver is absolutely unique over all slices and aggregates.
     746
     747The Sliver Info Service supports these standard API methods for type="SLIVER_INFO":
     748
     749|| ''' Method ''' || ''' Description ''' ||
     750|| create || Registers  new sliver info with provided details  ||
     751|| update || Updates given sliver info ||
     752|| delete || Deletes given sliver info ||
     753|| lookup || lookup sliver info matching given match criteria subject to authorization restrictions. ||
     754
     755
     756== Project Service Methods ==
     757
     758Projects are groupings of slices and members for a particular administrative purpose. Some SA;s will chose to create and manage projects and apply policies about the invocation of SA methods (e.g. the creation of slice credentials based on roles or memberships in projects). A slice can belong to no more than one project; a project may have many slice members.
     759
     760The following table contains required fields for project objects and whether they are allowed in lookup ‘match’ criteria, required at creation or allowed at update:
     761
     762|| ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Creation ''' || ''' Update ''' ||
     763|| PROJECT_URN || URN || URN of given project || Yes || No || No ||
     764|| PROJECT_UID ||UID || UID (unique within authority) of project || Yes || No || No ||
     765|| PROJECT_CREATION || DATETIME || Creation time of project || No || No || No ||
     766|| PROJECT_EXPIRATION || DATETIME || Expiration time of project || No || Required || Yes ||
     767|| PROJECT_EXPIRED || BOOLEAN || Whether project has expired || Yes || No || No ||
     768|| PROJECT_NAME || STRING || Short name of Project || No || Required || No ||
     769|| PROJECT_DESCRIPTION || STRING || Description of Project || No || Allowed || Yes ||
     770
     771The Project Service supports these standard API methods for type="PROJECT":
     772
     773|| ''' Method ''' || ''' Description ''' ||
     774|| create || Creates a new project with provided details  ||
     775|| update || Updates given project ||
     776|| delete || Deletes given project. Note: should fail if there are any active slices associated with project. ||
     777|| lookup || lookup projects matching given match criteria subject to authorization restrictions. ||
     778
     779
     780== Project Member Service Methods ==
     781
     782Projects may have members associated with them in particular roles and thus supports the same methods for member management as described above for the Slice Member Service. The differences are that the type provide is "PROJECT", the urn provided is a project URN and the membership information returned is tagged with "PROJECT_URN' and 'PROJECT_ROLE' as appropriate.
     783
     784|| ''' Method ''' || ''' Description ''' ||
     785|| modify_membership || Adds/removes/changes roles of members with respect to given project   ||
     786|| lookup_members || Returns list of {PROJECT_MEMBER, PROJECT_ROLE} dictionaries| for members projects matching given criteria ||
     787|| lookup_for_member || Returns list of {PROJECT_URN, PROJECT_RULE} dictionaries for projects to which a given member belongs ||
     788
     789
     790== Member Authority API ==
     791
     792The Member Authority API provides services to manage information about federation members including public and potentially private or identifying information.
     793
     794As noted above, this document does not specify required policies for Federations. A given MA is free to implement its own policies. That said, the management of member private information is a subject for particular attention and care.
     795
     796All MA calls are protected; passing and validating a client-side cert is required.
     797
     798 While each MA is free to implement its own authorization policy, reasonable security policy should allow calls to succeed only if the following criteria are met:
     799
     800 * The user/tool cert is signed by someone in the Federation's trust chain
     801 * If the cert is held by a tool, then the call must contain a user cert and a ‘speaks-for’ credential and the tool is trusted by the Federation to perform speaks-for.
     802 * The requestor is asking for their own identifying info or has privileges with respect to the people about whom they are asking for that identifying info.
     803 * Access to private info (SSL or SSH keys) should be restricted only to the user’s own keys for ordinary users.
     804
     805Like the Slice Authority, the Member Authority provides a set of services each consisting of a set of methods. Some services are required for any MA implementation, others are optional, as indicated by this table:
     806
     807|| '''Service''' || '''Description''' || '''Required''' || '''Object'''
     808|| MEMBER || Services to  lookup and update information about members || YES || MEMBER ||
     809|| KEY || Services to support storing, deleting and retrieving keys (e.g. SSH)  for members || NO || KEY ||
     810
     811== Member Service Methods ==
     812
     813The information managed by the MA API is divided into three categories, for purposes of applying different AuthZ policies at these different levels:
     814
     815 * Public: Public information about a member (e.g. public SSH or SSH keys, speaks-for credentials, certificates)
     816 * Private: Private information (e.g. private SSL or SSH keys) that should be given only to the member or a tool speaking for the member with a valid speaks-for credential
     817 * Identifying: Information that could identify the given member (e.g. name, email, affiliation)
     818
     819The following table contains required fields for member objects and whether they are allowed in lookup ‘match’ criteria and their protection (public, private, identifying):
     820
     821
     822|| ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Protection ''' ||
     823|| MEMBER_URN || URN || URN of given member || Yes || Public ||
     824|| MEMBER_UID ||UID || UID (unique within authority) of member || Yes || Public ||
     825|| MEMBER_FIRSTNAME || STRING || First name of member || Yes || Identifying ||
     826|| MEMBER_LASTNAME || STRING || Last name of member || Yes || Identifying ||
     827|| MEMBER_USERNAME || STRING || Username of user || Yes || Public ||
     828|| MEMBER_EMAIL || STRING || Email of user || Yes || Identifying ||
     829
     830The MEMBER Service supports these standard API methods for type="MEMBER":
     831
     832|| ''' Method ''' || ''' Description ''' ||
     833|| update ||  update info associated with given member by URN ||
     834|| lookup || lookup info associated with members matching match criteria. ||
     835
     836Note: the ''lookup' call provides public information for all members matching the 'match' criteria. It will also provide identifying (e.g. email or name) or private (e.g. SSL private key) information for members for whom the caller is authorized.
     837When a field requested is unauthorized, the key will not be provide in the returned dictionary for that member.
     838When the field requested has a key but a blank/null value, the access is authorized but the value for that field is, in fact, blank.
     839A blank (null, not empty list) fields option indicates that the caller wants to see all fields to which the caller  is authorized. If a list of fields is specified in the fields option, only those authorized fields from among the specified set is provided for each matched member.
     840
     841The following are additional methods provided by the MEMBER service:
     842
     843{{{
     844#!python
     845# Provide list of credentials (signed statements) for given member
     846# This is member-specific information suitable for passing as credentials in
     847#  an AM API call for aggregate authorization.
     848# Arguments:
     849#    member_urn: URN of member for which to retrieve credentials
     850#    options: Potentially contains ‘speaking_for’ key indicating a speaks-for
     851#        invocation (with certificate of the accountable member in the credentials argument)
     852#
     853# Return:
     854#     List of credential in “CREDENTIALS” format, i.e. a list of credentials with
     855#        type information suitable for passing to aggregates speaking AM API V3.
     856def get_credentials(member_urn, credentials, options)
     857}}}
     858
     859== Key Service Methods ==
     860
     861The Key Service provides methods to allow for storing, deleting and retrieving SSH or similar keys for members. It is not intended for retrieving SSL public/private keys or certs.
     862
     863The following table contains the required fields for key objects and whether they are allowed in lookup 'match' criteria, required at creation or allowed at update:
     864
     865|| '''Name''' || '''Type''' || '''Description''' || '''Match''' || '''Creation''' || '''Update''' ||
     866|| KEY_MEMBER || URN || URN of member associated with key pair || Yes || Required || No ||
     867|| KEY_ID || STRING || Unique identifier for member/key pair: typically a fingerprint or hash of public key joined with member information || Yes || No || No ||
     868|| KEY_TYPE || STRING || Type of key (e.g. PEM, openssh, rsa-ssh) || Yes || Required || No ||
     869|| KEY_PUBLIC || KEY || Public key value || Yes || Required || No ||
     870|| KEY_PRIVATE || KEY || Private key value || Yes || Allowed || No ||
     871|| KEY_DESCRIPTION || STRING || Human readable description of key pair || Yes || Allowed || Yes ||
     872
     873
     874The Key Service supports these standard API methods for type="KEY":
     875
     876|| ''' Method ''' || ''' Description ''' ||
     877|| create || Creates a new record for a key associated with a member. The 'KEY_ID' returned from this call is the unique identifier for this key for this member and can be used as the 'urn' variable in the other key management API calls below. ||
     878|| update || urn is the key_id ||
     879|| delete || urn is the key_id ||
     880|| lookup || lookup keys matching given match criteria subject to authorization restrictions. ||
     881
     882Note that access to key information is subject to authorization policy. The public keys are likely to be readily available but access to the private keys will be tightly restricted (often only to the user or authorized proxy). Requests to lookup key information for prohibited filter criteria results in omitting these fields. For example, if one asks for KEY_PUBLIC and KEY_PRIVATE for a list of member_urn's, the result may return both KEY_PUBLIC and KEY_PRIVATE for certain (permitted) users, and only KEY_PUBLIC for other (restricted) users.
     883
     884
     885== Appendix: Federation Object Models ==
     886
     887As described, each Federation service method takes a set of options that provide further details on the request. Many of these options reflect the fields of the underlying object models. For example, the Slice Authority manages slice objects and allows for options for querying for and by slice object fields.
     888
     889Different Federation Authorities will implement different subsets of the possible set of Federation services. Those that do implement a given service should implement the API’s described above. The fields of the objects maintained through these API’s are flexible: some fields are required but different Authorities may have their own additional data, to be returned by the get_version method.
     890
     891The following diagram reflects the different objects maintained within the full range of Authority services, their interactions and mandatory fields.
     892
     893[[Image(FedObjectModel.png, 50%,nolink)]]
     894
     895== Appendix B: API Data Types ==
     896
     897The following table describes the data types referenced in the document above, in terms of format and meaning.
     898
     899|| ''' Type ''' || ''' Description ''' || ''' Format ''' ||
     900|| URN || Standard GENI identifier, guaranteed to be unique across all GENI services and authorities at a given time, but may be reused by obsolete/expired objects (e.g. slices) || '''Example:''' urn:publicid:IDN+mych+user+abrown ''' Details: ''' urn:publicid:IDN+AUTHORITY+TYPE+NAME where AUTHORITY is the unique fully qualified identifier of the authority creating the URN (e.g. ch.geni.net), TYPE is the type of entity (e.g. slice, user, tool, project) and name is the unique name of the entity (e.g. slice_name, user_name, tool_name, project_name). See  http://groups.geni.net/geni/wiki/GeniApiIdentifiers  for data type definitions. ||
     901|| UID || Unique identifier within the scope of a single authority, not guaranteed to be unique across authorities || '''Example:''' 8e405a75-3ff7-4288-bfa5-111552fa53ce '''Details:''' Varies by implementation but the python UUID4 standard is a good example.  See RFC4122 standard http://www.ietf.org/rfc/rfc4122.txt ||
     902|| STRING || Generic UTF-8 string ||  ||
     903|| INTEGER || Generic integer argument || ||
     904|| DATETIME || String representing a date/time in RFC3339 format  (http://tools.ietf.org/html/rfc3339).  || '''Examples:''' 2013-06-15T02:39:08+03:00,  2013-06-15T02:39:08-05:00, 2014-02-23T11:00:05Z '''Details''': DATETIME values in the Federation API will be strings in RFC3339-compliant format. We ''recommend'' that implementers use parsers that fully comply with this standard. However, due to the flexibility in the spec and different interpretations chosen by different common parsers, we ''require'' that such DATETIME values: 1) contain an uppercase T between the time and date portions, 2) contain a timezone suffix, either an uppercase Z (for UTC) or +/-HH:MM, and 3) do not contain fractional seconds.||
     905|| EMAIL || Well-formed email address compliant with RFC2822 http://tools.ietf.org/html/rfc2822#section-3.4.1 || '''Example:''' jbrown@geni.net ||
     906|| KEY || SSH or SSL public or private key (contents, not filename) || Key-specific format ||
     907|| BOOLEAN || XMLRPC encoded boolean || '''Example:''' True ||
     908|| CREDENTIALS || List of dictionaries, one per credential, tagged with credential type and version (as indicated in the GENI AM API specification) || '''Details:''' Credentials = [ { geni_type: <string, case insensitive>, geni_version: <string containing an integer>, geni_value : <credential as string>, <others> } ]. See http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#credentials or http://groups.geni.net/geni/wiki/GeniApiCertificates for credential format and semantic specification.  ||
     909|| CERTIFICATE || X509 v3 certificate (contents, not filename) || Standard X509 v3 PEM certificate format. A chain of such certificates may be concatenated.  See  http://en.wikipedia.org/wiki/X.509 and http://groups.geni.net/geni/wiki/GeniApiCertificates for more details ||
     910
     911As noted above, this list is subject to change as the API develops over time.
     912
     913== Appendix C: API V1 and V2 Mappings ==
     914
     915Federation API V2 makes significant changes to the previous (V1) Federation API. Specifically, it generalizes many of the API calls thy introducing  a 'type' argument. This table summarizes the changes to V1 calls and their equivalent in V2.
     916
     917|| ''' Authority ''' || ''' V1 method ''' || ''' V2 alternative '' ||
     918|| Federation Registry || || ||
     919||   || lookup_aggregates || lookup(type="AGGREGATE_MANAGER") ||
     920||  || lookup_slice_authorities || lookup(type="SLICE_AUTHORITY") ||
     921||  || lookup_member_authorities || lookup(type="MEMBER_AUTHORITY") ||
     922|| Slice Authority || || ||
     923|| || create_slice || create(type="SLICE") ||
     924|| || lookup_slices || lookup(type="SLICE") ||
     925|| || update_slice || update(type="SLICE") ||
     926|| || modify_slice_membership || modify_membership(type="SLICE") ||
     927|| || lookup_slice_members || lookup_members(type="SLICE") ||
     928|| || lookup_slices_for_member || lookup_for_member(type="SLICE")  ||
     929|| || create_sliver_info || create(type="SLIVER_INFO") ||
     930|| || delete_sliver_info |} delete(type="SLIVER_INFO") ||
     931|| || update_sliver_info || update(type="SLIVER_INFO") ||
     932|| || lookup_sliver_info || lookup(type="SLIVER_INFO") ||
     933|| || create_project || create(type="PROJECT") ||
     934|| || lookup_projects || lookup(type="PROJECT") ||
     935|| || update_project || update(type="PROJECT") ||
     936|| || modify_project_membership || modify_membership(type="PROJECT") ||
     937|| || lookup_project_members || lookup_members(type="PROJECT") ||
     938|| || lookup_projects_for_member || lookup_for_member(type="PROJECT") ||
     939|| Member Authority || || ||
     940|| || lookup_public_member_info || lookup(type="MEMBER") with fields option containing list of public fields only ||
     941|| || lookup_identifying_member_info || lookup(type="MEMBER") with fields option containing list of identifying fields only ||
     942|| || lookup_private_member_info || lookup(type="MEMBER") with fields option containing list of private fields only ||
     943|| || update_member_info || update(type="MEMBER") ||
     944|| || create_key || create(type="KEY") ||
     945|| || delete_key || delete(type="KEY") ||
     946|| || update_key || update(type="KEY") ||
     947|| || lookup_keys || lookup(type="KEY") ||