Changes between Version 40 and Version 41 of UniformClearinghouseAPIV2


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

--

Legend:

Unmodified
Added
Removed
Modified
  • UniformClearinghouseAPIV2

    v40 v41  
    1 [[PageOutline(1-2, Table of Contents)]]
    2 == GENI Federation API’s ==
    3 Marshall Brinn, GPO
    4 
    5 API Version 2 
    6 
    7 Revised: November 13, 2013
    8 
    9 
    10 == Introduction ==
    11 
    12 
    13 
    14 This 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 
    16 The 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 
    24 There 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 
    29 A '' 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 
    31 The 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 
    33 Authorities 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 
    35 This 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 
    48 The 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 
    57 These 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 (…)
    73 def fed_func (arg1, arg2, credentials, options)
    74 }}}
    75 
    76 
    77 == API 'get_version' methods ==
    78 
    79 Different 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 
    81 Each 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 
    98 The 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 
    100 The 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 
    108 Supplementary 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 
    110 The 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 
    118 The 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 
    120 The 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
    130 def get_version()
    131 }}}
    132 
    133 
    134 The following page provides some example returns from different get_version calls.
    135 
    136 == Example get_version returns: ==
    137 
    138 The 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 
    166 The 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 
    184 TRUE, “PROTECT”: “IDENTIFYING”},
    185 
    186       “MEMBER_AFFILIATION”: {“TYPE”: “STRING”, “CREATE”: “ALLOWED”, “UPDATE”:
    187 
    188 TRUE, “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 
    203 The 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 
    222 All 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 
    224 Each 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 
    238 Each 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 #
    262 def 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 #
    285 def 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 #
    302 def 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 #
    329 def lookup (type, credentials, options)
    330 }}}
    331 
    332 Some additional details on the lookup call:
    333 
    334 The 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 
    336 The 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 
    338 The 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 
    340 The 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 
    342 If 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 
    347 A 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 
    355 Such 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 
    379 A 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 
    389 An 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 
    411 An 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 
    429 and 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 
    457 This 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 
    461 Best 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 
    463 Accordingly, 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 
    469 The 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 
    471 Aggregates 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 
    475 The 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 
    477 All 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 
    479 The Federation Registry implements the SERVICE service and supports the SERVICE object.
    480 
    481 Services 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 
    492 This 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 
    502 The 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 
    514 The 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.
    515 It 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.
    516 The current service URL (provided in the SERVICE_URL field) should always be included in the SERVICE_PEERS.
    517 The 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.
    518 An 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 
    527 The Federation Registry API supports these standard API methods for type="SERVICE":
    528 
    529 || ''' Method ''' || ''' Description ''' ||
    530 || lookup || lookup services matching given match criteria. ||
    531 
    532 Note 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 
    534 Additionally, 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.
    551 def 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
    567 def lookup_authorities_for_urns(urns)
    568 }}}
    569 
    570 The ''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 
    579 The 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 
    581 All SA calls are protected; passing and validating a client-side cert is required.
    582 
    583 The 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 
    595 The 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 
    597 The 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 
    601 Note 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 
    603 The 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 
    615 To 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 
    617 NB: 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 
    619 The 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 
    627 Additionally, 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.
    652 def get_credentials(slice_urn, credentials, options)
    653 }}}
    654 
    655 == Slice Member Service Methods ==
    656 
    657 Slices 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 
    659 The 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 
    661 The 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
    689 def 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.
    709 def 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
    726 def lookup_for_member(type, member_urn, credentials, options)
    727 }}}
    728 
    729 == Sliver Info Service Methods ==
    730 
    731 Sliver 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 
    733 It 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 
    735 The 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 
    745 Note 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 
    747 The 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 
    758 Projects 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 
    760 The 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 
    771 The 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 
    782 Projects 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 
    792 The Member Authority API provides services to manage information about federation members including public and potentially private or identifying information.
    793 
    794 As 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 
    796 All 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 
    805 Like 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 
    813 The 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 
    819 The 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 
    830 The 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 
    836 Note: 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.
    837 When a field requested is unauthorized, the key will not be provide in the returned dictionary for that member.
    838 When 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.
    839 A 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 
    841 The 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.
    856 def get_credentials(member_urn, credentials, options)
    857 }}}
    858 
    859 == Key Service Methods ==
    860 
    861 The 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 
    863 The 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 
    874 The 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 
    882 Note 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 
    887 As 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 
    889 Different 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 
    891 The following diagram reflects the different objects maintained within the full range of Authority services, their interactions and mandatory fields.
    892 
    893 [[Image(FedObjectModel.pdf, 50%,nolink)]]
    894 
    895 == Appendix B: API Data Types ==
    896 
    897 The 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 
    911 As noted above, this list is subject to change as the API develops over time.
    912 
    913 == Appendix C: API V1 and V2 Mappings ==
    914 
    915 Federation 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") ||
     1The [wiki:CommonFederationAPIv2 Common Federation API v2] page has moved. The new location is: http://groups.geni.net/geni/wiki/CommonFederationAPIv2