Changes between Version 82 and Version 83 of UniformClearinghouseAPI


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

--

Legend:

Unmodified
Added
Removed
Modified
  • UniformClearinghouseAPI

    v82 v83  
    1 [[PageOutline(1-2, Table of Contents)]]
    2 == GENI Federation API’s ==
    3 Marshall Brinn, GPO
    4 
    5 API Version 1
    6 Revised: November 12, 2013
    7 
    8 
    9 == Introduction ==
    10 
    11 
    12 
    13 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.
    14 
    15 The GENI Software Architecture rests on the interaction between different entities:
    16 
    17 ''' Aggregates ''' : Collections of resources managed and presented in accordance with the AM API
    18 
    19 ''' Members ''' : Experimenters or other human consumers of aggregate resources
    20 
    21 ''' Authorities ''' : Services that manage assertions about members and their permissions with respect to aggregate resources.
    22 
    23 There are two fundamental authority types in GENI:
    24 
    25  * '' Member Authority '' [MA]: Manages and asserts attributes about particular members
    26  * '' Slice Authority '' [SA]: Manages slice objects and generates credentials for members with respect to slices.
    27 
    28 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 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 Registries is 1:1.
    29 
    30 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.
    31 
    32 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 Registry may choose to advertise or not advertise any particular aggregate, regardless of whether that aggregate trusts the Authorities advertised by that Registry. Similarly, a given Slice Authority or Member Authority may be advertised by a single Registries or by multiple Registries. Registry API calls are unprotected. There is no notion of trust between Registries or between Registries and Authorities or Aggregates.
    33 
    34 This document describes the APIs of the Registry as well as the MA and SA. It is expected that a well-behaved GENI-compatible tool will allow for interacting with any Registry and Authority that implement the standard API’s described in this document.
    35 
    36 
    37 
    38 
    39 
    40 
    41 
    42 
    43 
    44 
    45 == API General Properties ==
    46 
    47 The APIs described here share some common properties, which should be assumed for the rest of this document:
    48  * The wire-protocol is XML/RPC. It is thus language independent on both client and server side of the API calls.
    49  * 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.
    50  * Each call takes an ‘options’ argument, a dictionary allowing for passing specific non-standard/optional arguments
    51  * Each protected method takes a ‘credentials’ argument, a list of type/credential tuples that help the Registry or Authority invoke whatever AuthZ logic it may choose. As noted above, the Registry or Authority may choose to use or disregard these credentials. Unprotected methods do not take a ‘credentials’ argument.
    52  * Each 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.
    53  * A Registry or Authority is free to implement additional methods beyond those specified in this document.
    54  * 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.
    55 
    56 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.
    57 
    58 {{{
    59 #!python
    60 # Perform method fed_func
    61 #
    62 # Arguments:
    63 #  argl : ...
    64 #  credentials : list of {type : credential} tuples representing credentials provided by caller to support AuthZ on method call.
    65 #      [NB: This argument will be omitted in descriptions below. ]
    66 #  options : … [ Recognized options: ….]
    67 #
    68 # Return:
    69 #  E.g. a list of dictionaries with these fields mandatory (…) and these fields optional (…)
    70 def fed_func (arg1, arg2, credentials, options)
    71 }}}
    72 
    73 
    74 == API 'get_version' methods ==
    75 
    76 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.
    77 
    78 Each 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):
    79  * VERSION: A string with the version number of the Federation API (e.g. “10.0.7”). Note: this is the version of the API not the version of the implementation. This field is mandatory for all services.
    80  * SERVICES: The set of services the given URL supports   
    81  * CREDENTIAL_TYPES: A list of recognized credential types (e.g. [ABAC, SFA]) and list of supported credential versions on protected API methods.  ''[Authorities only]''
    82  * ROLES : A list of recognized roles for slice/project membership (optional for those Slice Authorities supporting membership).  ''[SA only]''
    83  * FIELDS: A dictionary of '''''supplementary''''' object field names (i.e. in additional to the required fields) and associated attributes including:
    84      * “OBJECT” provides the object to which the field belongs (if not the default authority object, i.e. SLICE for Slice Authority, MEMBER for Member Authority, Service for Registry). This field is mandatory for any field listed.
    85      * “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.
    86      * “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.
    87      * "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.
    88      * “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.
    89      * “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.
    90 
    91 The FIELDS element of the get_version is optional for all services, as it only contains supplementary fields (which may not exist for a given service).
    92 
    93 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.).
    94 
    95 The return from the get_version call will be used to construct and validate options to Registry and Authority API calls, as described in subsequent sections.
    96 
    97 The following page provides some example returns from different get_version calls.
    98 
    99 == Example get_version returns: ==
    100 
    101 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:
    102 
    103 {
    104 
    105 “VERSION”: “10.0.7”,
    106 
    107 “SERVICES”: [“SLICE”, “PROJECT”, “SLICE_MEMBER”, “PROJECT_MEMBER”],
    108 
    109 "OBJECTS": [ "PROJECT" ],
    110 
    111 “CREDENTIAL_TYPES”: {“SFA”: [ "1" ]}, “ABAC” : ["1", "2"]},
    112 
    113 “ROLES” : [“LEAD”, “ADMIN”, “MEMBER”, “AUDITOR”, “OPERATOR” ],
    114 
    115 “FIELDS”: {
    116      
    117      "_GENI_PROJECT_UID": {"TYPE" : "UID", "UPDATE" : FALSE},
    118 
    119      “_GENI_SLICE_EMAIL”: {“TYPE”: “EMAIL”, “CREATE”: “REQUIRED”, “UPDATE”: TRUE},
    120      
    121      “_GENI_PROJECT_EMAIL”: {“TYPE”: “EMAIL”, “CREATE”: “REQUIRED”, “UPDATE”: TRUE, “OBJECT”: “PROJECT”}
    122        
    123       }
    124 
    125 }
    126 
    127 The following is an example of a return from a get_version for an MA, provided in JSON-like syntax:
    128 
    129 {
    130 
    131       “VERSION”: “10.0.7”,
    132 
    133       “CREDENTIAL_TYPES”: [“SFA”, “ABAC”],
    134 
    135       "SERVICES": ["MEMBER", "KEY"],
    136 
    137       "OBJECTS": [ "KEY" ],
    138 
    139       “FIELDS”: {
    140    
    141               “MEMBER_DISPLAYNAME”: {“TYPE”: “STRING”, “CREATE”: “ALLOWED”, “UPDATE”,
    142 
    143 TRUE, “PROTECT”: “IDENTIFYING”},
    144 
    145       “MEMBER_AFFILIATION”: {“TYPE”: “STRING”, “CREATE”: “ALLOWED”, “UPDATE”:
    146 
    147 TRUE, “PROTECT”: “IDENTIFTYING”},
    148 
    149       “MEMBER_SSL_PUBLIC_KEY”: {“TYPE”: “SSL_KEY”},
    150 
    151       “MEMBER_SSL_PRIVATE_KEY”: {“TYPE”: “SSL_KEY”, “PROTECT”: “PRIVATE”},
    152 
    153       “MEMBER_SSH_PUBLIC_KEY”: {“TYPE”: “SSH_KEY”},
    154 
    155       “MEMBER_SSH_PRIVATE_KEY”: {“TYPE”: “SSH_KEY”, “PROTECT”: “PRIVATE”},
    156 
    157       “MEMBER_ENABLED”: {“TYPE”: “BOOLEAN”, “UPDATE”: TRUE}
    158     }
    159 
    160 }
    161 
    162 The following is an example of a return from a get_version from a Registry, provided in JSON-like syntax:
    163 
    164 {
    165       “VERSION”: “10.0.7”,
    166 
    167       “FIELDS”: {
    168 
    169               “SERVICE_PROVIDER”: {“TYPE”: “STRING”}}
    170 
    171      }
    172 
    173 }
    174 
    175 == API Error Handing ==
    176 
    177 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).
    178 
    179 Each 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:
    180 
    181 || ''' CODE_NAME ''' || ''' CODE_VALUE ''' || ''' DESCRIPTION ''' ||
    182 || 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’. ||
    183 || 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 ||
    184 || AUTHORIZATION_ERROR || 2 || The invoking tool or member does not have the authority to invoke the given call with the given arguments ||
    185 || ARGUMENT_ERROR || 3 || The arguments provided to the call were mal-formed or mutually inconsistent. ||
    186 || DATABASE_ERROR || 4 || An error from the underlying database was returned. (More info should be provided in the ‘output’ return value] ||
    187 || DUPLICATE_ERROR || 5 || An error indicating attempt to create an object that already exists ||
    188 || NOT_IMPLEMENTED_ERROR || 100 || The given method is not implemented on the server. ||
    189 || SERVER_ERROR || 101 || An error in the client/server connection ||
    190 
    191 == API Method Conventions ==
    192 
    193 Each Registry and Authority manages the state of or access to objects. Some conventions apply to similar methods across Registry or Authority services.
    194 
    195 ''' Create_*Method ''' : Creates a new instance of the given object with a ‘fields’ option specifying particular field values that are to be associated with the object. These may only include those fields specified as ‘ALLOWED or ‘REQUIRED’ in the ‘Creation’ column of the object descriptions below or in the “CREATE’ key in the supplemental fields in the get_version specification for that object. If successful, the call returns a dictionary of the fields associated with the newly created object.
    196 
    197 ''' Update_* Method ''' : Updates an object instance specified by URN with a ‘fields’ option specifying the particular fields to update. Only a single object can be updated from a single update call. The fields may include those specified as ‘Yes’ in the ‘Update’ column of the object descriptions below, or ’TRUE’ in the ‘UPDATE’ key in the supplemental fields provided by the get_version call. Note: There may be more than one entity of a given URN at an authority, but only one ‘live’ one (any other is archived and cannot be updated).
    198 
    199 ''' Lookup_* Method ''' : This call takes a set of ‘match’ criteria provided in the ‘options’ field, and returns a dictionary of dictionaries of object attributes keyed by object URN matching these criteria. If a ‘filter’ option is provided, only those attributes listed in the ‘filter’ options are returned. The requirements on match criteria supported by a given service are service-specific; however it is recommended that policies restrict lookup calls to requests that are bounded to particular sets of explicitly listed objects (and not open-ended queries).
    200 
    201 Specifically, 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).
    202 
    203 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.
    204 
    205 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).
    206 
    207 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).
    208 
    209 If a lookup method asks for information about objects whose disclosure is prohibited to the requestor by policy, the method must not return the data. It is implementation specified as to whether the call should return an error, return a dictionary with the URN key pointing to an empty dictionary, or have no URN key in the returned dictionary.
    210 
    211 == API Method Examples: ==
    212 
    213 A Member Authority (MA) manages information about member objects. The MA method lookup_member could take an options argument such as
    214 
    215 {
    216 
    217       "match”: {“MEMBER_LASTNAME”: “BROWN”},
    218      
    219       "filter”: [“MEMBER_EMAIL”, “MEMBER_FIRSTNAME”]
    220 
    221 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.
    222 
    223 ''' { '''
    224 
    225       “urn:publicid:IDN+mych+user+abrown” :
    226      
    227             {“MEMBER_EMAIL”: abrown@williams.edu,
    228            
    229             “MEMBER_FIRSTNAME”: “Arlene”},
    230      
    231       “urn:publicid:IDN+mych+user+mbrown” :
    232 
    233             {“MEMBER_EMAIL”: mbrown@umass.edu,
    234 
    235             “MEMBER_FIRSTNAME”: “Michael”},
    236 
    237       “urn:publicid:IDN+mych+user+sbrown” :
    238 
    239             {“MEMBER_EMAIL”: sbrown@stanford.edu,
    240 
    241             “MEMBER_FIRSTNAME”: “Sam”}
    242 
    243 }
    244 
    245 A Slice Authority (SA) manages information about slice objects. The SA method update_slice could take an options ‘update’ argument such as to change the slice description and extend the slice expiration:
    246 
    247 {
    248 
    249       “fields” : { “SLICE_DESCRIPTION”: “Updated Description”,
    250 
    251                  “SLICE_EXPIRATION”: “2013-07-29T13:15:30Z” } 
    252 
    253 }
    254 
    255 An example of lookup_slice that wanted to retrieve the slice names for a list of slice URNs could specify options:
    256 
    257 {“match”: {
    258 
    259       “SLICE_URN”: [
    260 
    261              “urn:publicid+IDN+this_sa:myproject+slice+slice1”,
    262 
    263              “urn:publicid+IDN+this_sa:myproject+slice+slice2”,
    264 
    265              “urn:publicid+IDN+this_sa:myproject+slice+slice3”
    266 
    267        ]},
    268 
    269 “filter”: [“SLICE_NAME”]
    270 
    271 }
    272  
    273 
    274 == API Method Examples (cont.): ==
    275 
    276 An example of create_slice call would specify required options e.g.:
    277 
    278 {
    279  
    280       ‘fields’ : {
    281 
    282             “SLICE_NAME”: “TEST_SLICE”,
    283            
    284             “SLICE_DESCRIPTION”: “My Test Slice”,
    285 
    286             “SLICE_EMAIL”: myemail@geni.net,
    287 
    288             “PROJECT_URN”: “urn:publicid+IDN+this_sa+project+myproject”
    289 
    290        }
    291 
    292 }
    293 
    294 and receive a return dictionary looking like:
    295 
    296 {
    297 
    298        “SLICE_URN”: “urn:publicid+IDN+this.sa+slice+TESTSLICE”,
    299 
    300        “SLICE_UID”: “…”,
    301 
    302        “SLICE_NAME”: “TESTSLICE”,
    303 
    304        “SLICE_CREDENTIAL”: “.....”,
    305 
    306        “SLICE_DESCRIPTION”: “My Test Slice”,
    307 
    308        “PROJECT_URN”: “urn:publicid+IDN+this_sa+project+myproject”,
    309 
    310        “SLICE_EXPIRATION”: “2013-08-29T13:15:30Z”,
    311 
    312        “SLICE_EXPIRED”: “FALSE”,
    313 
    314        “SLICE_CREATION”: “2013-07-29T13:15:30Z”,
    315 
    316        “SLICE_EMAIL”: myemail@geni.net
    317 
    318 }
    319 
    320 == API Authentication ==
    321 
    322 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.
    323 
    324 == Support for Speaks-for API Invocations ==
    325 
    326 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.
    327 
    328 Accordingly, a 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:
    329 
    330 - A 'speaking-for' option containing the URN of the user being spoken for
    331 
    332 - 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).
    333 
    334 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.
    335 
    336 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.
    337 
    338 == Registry API ==
    339 
    340 The 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 Registry) is to be provided out-of-band (i.e. there is no global service for gaining access to Registry addressees).
    341 
    342 All Registry calls are unprotected; they have no requirement for passing a client-side cert or validating any client-cert cert that is passed.
    343 
    344 The Registry implements the SERVICE service and supports the SERVICE object.
    345 
    346 The following table describes the default fields for services (aggregates and authorities) provided by Registry API calls:
    347 
    348 
    349 || ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Required ''' ||
    350 || SERVICE_URN || URN || URN of given service || Yes ||
    351 || SERVICE_URL ||URL || URL by which to contact the service || Yes ||
    352 || SERVICE_CERT || Certificate || Public certificate of service || No ||
    353 || SERVICE_NAME || String || Short name of service || Yes ||
    354 || SERVICE_DESCRIPTION || String || Descriptive name of service || No ||
    355 
    356 {{{
    357 #!python
    358 # Provide a structure detailing the version information as well as details of accepted options for Registry API calls.
    359 #
    360 # Arguments:
    361 #   None
    362 #
    363 # Return:
    364 #   get_version structure information as described above
    365 def get_version()
    366 }}}
    367 
    368 {{{
    369 #!python
    370 # Return information about all aggregates associated with the Federation
    371 #
    372 # Arguments:
    373 #  options: 'match' and 'filter' options   as described in standard lookup methods
    374 #
    375 # Return:
    376  #  List of dictionaries of name/value pairs for each returned AM
    377 def lookup_aggregates(options)
    378 }}}
    379 
    380 {{{
    381 #!python
    382 #
    383 # Return information about all MA’s associated with the Federation#
    384 #
    385 # Arguments:
    386 #  options: 'match' and 'filter' options   as described in standard lookup methods
    387 #
    388 #Return:
    389 #  List of dictionaries of name/value pairs for each returned MA
    390 def lookup_member_authorities(options)
    391 }}}
    392 
    393 {{{
    394 #!python
    395 # Return information about all SA’s associated with the Federation
    396 #
    397 # Arguments:
    398 #   options: 'match' and 'filter' options   as described in standard lookup methods
    399 #
    400 # Return:
    401 #   List of dictionaries of name/value pairs for each returned SA
    402 def lookup_slice_authorities(options)
    403 }}}
    404 
    405 
    406 The following 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:
    407 
    408 || '''Type''' || '''Object URN''' || '''Authority URN''' ||
    409 || Slice || urn:publicid:IDN+sa_name+slice+slice_name || urn:publicid:IDN+sa_name+authority+sa ||
    410 || Member || urn:publicid:IDN+ma_name+user+user_name || urn:publicid:IDN+ma_name+authority+ma ||
    411 
    412 {{{
    413 #!python
    414 # Lookup the authorities for a given URNs
    415 #
    416 # There should be at most one (potentially none) per URN.
    417 #
    418 # This requires extracting the authority from the URN and then looking up the authority in the Registry's set of services.
    419 #
    420 # Arguments:
    421 #   urns: URNs of entities for which the authority is requested
    422 #
    423 # Return:
    424 #   List of dictionaries {urn : url} mapping URLs of Authorities to given URN's
    425 def lookup_authorities_for_urns(urns)
    426 }}}
    427 
    428 {{{
    429 #!python
    430 # Return list of trust roots (certificates) associated with this Federation.
    431 #
    432 # Often this is a concatenatation of the trust roots of the included authorities.
    433 #
    434 # Arguments:
    435 #   None
    436 #
    437 # Return:
    438 #   List of certificates representing trust roots of this Federation.
    439 def get_trust_roots()
    440 }}}
    441 
    442 == Slice Authority API ==
    443 
    444 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.
    445 
    446 All SA calls are protected; passing and validating a client-side cert is required.
    447 
    448 The following is a list of potential SA services.
    449 
    450 
    451 || ''' Service ''' || ''' Description ''' || ''' Required ''' || ''' Object ''' ||
    452 || SLICE || Managing generation, renewal of slice credentials and slice lookup services || YES || SLICE ||
    453 || SLICE_MEMBER ||Defining and managing roles of members with respect to slices || NO || ||
    454 || SLIVER_INFO || Providing information about what Aggregates have reported having slivers for a given slice. Non-authoritative/advisory || NO || SLIVER_INFO ||
    455 || PROJECT || Defining projects (groupings of slices) and project lookup services || NO || PROJECT ||
    456 || PROJECT_MEMBER || Defining and managing roles of members with respect to projects || NO || ||
    457 
    458 == Slice Service Methods ==
    459 
    460 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.
    461 
    462 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:
    463  * PI: The user has a PI lead and is typically considered appropriate for creating projects or slices (if there are no projects)
    464  * ADMIN: The user has special 'admin' privileges and can perform operations not otherwise authorized.
    465 
    466 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.
    467 
    468 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:
    469 
    470 || ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Creation ''' || ''' Update ''' ||
    471 || SLICE_URN || URN || URN of given slice || Yes || No || No ||
    472 || SLICE_UID ||UID || UID (unique within authority) of slice || Yes || No || No ||
    473 || SLICE_CREATION || DATETIME || Creation time of slice || No || No || No ||
    474 || SLICE_EXPIRATION || DATETIME || Expiration time of slice || No || Allowed || Yes ||
    475 || SLICE_EXPIRED || BOOLEAN || Whether slice has expired || Yes || No || No ||
    476 || SLICE_NAME || STRING || Short name of Slice|| No || Required || No ||
    477 || SLICE_DESCRIPTION || STRING || Description of Slice || No || Allowed || Yes ||
    478 || SLICE_PROJECT_URN || URN || URN of project to which slice is associated (if SA supports project) || Yes || Required (if SA supports project) || No ||
    479 
    480 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.
    481 
    482 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.
    483 
    484 {{{
    485 #!python
    486 # Provide details on the version, services and options supported by this SA
    487 #
    488 # Arguments:
    489 #    Options:
    490 #
    491 # Return:
    492 #   get_version structure information as described above
    493 def get_version()
    494 }}}
    495 
    496 {{{
    497 #!python
    498 # Create a new slice, optionally within a project. See generic create_* method description above.
    499 #
    500 # Arguments:
    501 #
    502 #   Options:
    503 #       'fields', a dictionary field/value pairs for object to be created
    504 #
    505 # Return:
    506 #   Dictionary of field/value pairs for created slice (e.g. slice URN, slice UUID, expiration and slice credential)
    507 #
    508 # Should return DUPLICATE_ERROR if creating a slice for which a non-expired slice of same name exists.
    509 def create_slice (credentials, options)
    510 }}}
    511 
    512 {{{
    513 #!python
    514 # Lookup slice detail for slices matching ‘match’ options.
    515 #
    516 # ‘filter’ options indicate what detail to provide. See generic lookup_* method description above.
    517 #
    518 # Arguments:
    519 #    options: What details to provide (filter options) for which slices (match options)
    520 #
    521 # Return: List of dictionaries with field/value pairs for each returned slice
    522 #
    523 def lookup_slices (credentials, options)
    524 }}}
    525 
    526 {{{
    527 #!python
    528 # Update fields in given slice object. See generic update_* method description above.
    529 #
    530 # Arguments:
    531 #   slice_urn: URN of slice to update
    532 #
    533 #    Options: Contains ‘fields’ key referring dictionary of name/value pairs to update
    534 # Return: None
    535 #
    536 def update_slice(slice_urn, credentials, options)
    537 }}}
    538 
    539 {{{
    540 #!python
    541 # Provide list of credentials for the invoking member relative to the given slice. If the invocation is in a speaks-for context, the credentials will be for the ‘spoken-for’ member, not the invoking tool.
    542 #
    543 # For example, this call may return a standard SFA Slice Credential and some ABAC credentials indicating the role of the member with respect to the slice.
    544 #
    545 # Note: When creating an SFA-style Slice Credential, the following roles typically allow users to operate at known GENI-compatible aggregates: "*" (asterisk) or the list of "refresh", "embed", "bind", "control" "info".
    546 #
    547 # Arguments:
    548 #   slice_urn: URN of slice for which to get member’s credentials
    549 #   options: Potentially contains ‘speaking-for’ key indicating a speaks-for invocation (with certificate of the accountable member in the credentials argument)
    550 # Return:
    551 #   List of credential in “CREDENTIALS” format, i.e. a list of credentials with type information suitable for passing to aggregates speaking AM API V3.
    552 def get_credentials(slice_urn, credentials, options)
    553 }}}
    554 
    555 == Slice Member Service Methods ==
    556 
    557 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.
    558 
    559 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.
    560 
    561 {{{
    562 #!python
    563 # Modify slice membership, adding, removing and changing roles of members with respect to given slice
    564 #
    565 # Arguments:
    566 #   Slice_urn: URN of slice for which to modify membership
    567 #   Options:
    568 #       members_to_add: List of member_urn/role tuples for members to add to slice of form {‘SLICE_MEMBER’ : member_urn, ‘SLICE_ROLE’ : role}
    569 #       members_to_remove: List of member_urn of members to remove from slice
    570 #       members_to_change: List of member_urn/role tuples for members whose role should change as specified for given slice of form {‘SLICE_MEMBER’ : member_urn, ‘SLICE_ROLE’ : role}
    571 #
    572 # Return:
    573 #   None
    574 def modify_slice_membership(slice_urn, credentials, options)
    575 }}}
    576 
    577 {{{
    578 #!python
    579 # Lookup members of given slice and their roles within that slice
    580 #
    581 # Arguments:
    582 #   slice_urn: URN of slice for which to provide current members and roles
    583 #
    584 # Return:
    585 #    List of dictionaries of member_urn/role pairs [{‘SLICE_MEMBER’: member_urn, ‘SLICE_ROLE’: role }...] where ‘role’ is a string of the role name
    586 def 'lookup_slice_members(slice_urn, credentials, options)
    587 }}}
    588 
    589 {{{
    590 #!python
    591 # Lookup slices for which the given member belongs
    592 #
    593 # Arguments:
    594 #   Member_urn: The member for whom to find slices to which it belongs
    595 #
    596 # Return:
    597 #    List of dictionary of slice_urn/role pairs [(‘SLICE_URN’ : slice_urn, ‘SLICE_ROLE’ : role} ...] for each slice to which a member belongs, where role is a string of the role name
    598 def lookup_slices_for_member(member_urn, credentials, options)
    599 }}}
    600 
    601 == Sliver Info Service Methods ==
    602 
    603 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.
    604 
    605 It is expected that the register_aggregate and remove_aggregate 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.
    606 
    607 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:
    608 
    609 || '''Name''' || '''Type''' || '''Description''' || '''Match''' || '''Creation''' || '''Update''' ||
    610 || SLIVER_INFO_SLICE_URN || URN || URN of slice for registered sliver || Yes || Required || No ||
    611 || SLIVER_INFO_URN || URN || URN of registered sliver || Yes || Required || No ||
    612 || SLIVER_INFO_AGGREGATE_URN || URN || URN of aggregate of registered sliver || Yes || Required || No ||
    613 || SLIVER_INFO_CREATOR_URN || URN || URN of member/tool that created the registered sliver || Yes || Required || No ||
    614 || SLIVER_INFO_EXPIRATION || DATETIME || Time of sliver expiration || No || Allowed || Yes ||
    615 || SLIVER_INFO_CREATION || DATETIME || Time of sliver creation || No || Allowed || No ||
    616 
    617 {{{
    618 #!python
    619 # Create a record of a sliver creation
    620 #
    621 # Arguments:
    622 #   options: 'fields' containing the fields for the sliver info  being registered at SA
    623 #
    624 # Return:
    625 # Dictionary of name/value pairs for created sliver_info record
    626 def create_sliver_info(credentials, options)
    627 }}}
    628 
    629 {{{
    630 #!python
    631 # Delete a sliver_info record
    632 #
    633 # Arguments:
    634 #    sliver_urn: urn of sliver whose record is to be deleted
    635 #
    636 # Return:
    637 #   True if succeeded
    638 #
    639 #Should return ARGUMENT_ERROR if no such sliver urn is registered
    640 def delete_sliver_info(sliver_urn, credentials, options)
    641 }}}
    642 
    643 {{{
    644 #!python
    645 # Update the details of a sliver_info record
    646 #
    647 #Arguments:
    648 #   sliver_urn: urn of sliver for which to update
    649 #   options: 'fields' containing fields for sliver_infos that are permitted for update
    650 #
    651 # Return:
    652 #   None
    653 #
    654 # Should return ARGUMENT_ERROR if no such sliver_urn is found
    655 def update_sliver_info(sliver_urn, credentials, options)
    656 }}}
    657 
    658 {{{
    659 #!python
    660 # Lookup sliver_info for given match criteria return fields in given filter criteria
    661 #
    662 # Arguments:
    663 #   options: 'match' for query match criteria, 'filter' for fields to be returned
    664 #
    665 # Return:
    666 #    Dictionary (indexed by sliver_urn) of dictionaries containing name/value pairs for all sliver_infos registered at this SA matching given criteria.
    667 def lookup_sliver_info(credentials, options)
    668 }}}
    669 
    670 == Project Service Methods ==
    671 
    672 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).
    673 
    674 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:
    675 
    676 || ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Creation ''' || ''' Update ''' ||
    677 || PROJECT_URN || URN || URN of given project || Yes || No || No ||
    678 || PROJECT_UID ||UID || UID (unique within authority) of project || Yes || No || No ||
    679 || PROJECT_CREATION || DATETIME || Creation time of project || No || No || No ||
    680 || PROJECT_EXPIRATION || DATETIME || Expiration time of project || No || Allowed || Yes ||
    681 || PROJECT_EXPIRED || BOOLEAN || Whether project has expired || Yes || No || No ||
    682 || PROJECT_NAME || STRING || Short name of Project || No || Required || No ||
    683 || PROJECT_DESCRIPTION || STRING || Description of Project || No || Allowed || Yes ||
    684 
    685 {{{
    686 #!python
    687 # Create project with given details. See generic create_* description above.
    688 #
    689 # Arguments:
    690 #   Options: 'fields', a dictionary of name/value pairs for newly created project.
    691 #
    692 # Return:
    693 #   Dictionary of name/value pairs of newly created project including urn
    694 #
    695 #Should return DUPLICATE_ERROR if creating a project for which a project of same name exists.
    696 def create_project(credentials, options)
    697 }}}
    698 
    699 {{{
    700 #!python
    701 # Lookup project detail for projects matching ‘match options.
    702 # ‘filter options indicate what detail to provide.
    703 #
    704 # Arguments:
    705 #    options: What details to provide (filter options) for which members (match options)
    706 #
    707 # Return:
    708 #    Dictionary of name/value pairs from ‘filter’ options for each project matching ‘match’ option criteria.
    709 def lookup_projects(credentials, options)
    710 }}}
    711 
    712 {{{
    713 #!python
    714 # Update fields in given project object, as allowed in Get_version advertisement. See generic update_* description above.
    715 #
    716 # Arguments:
    717 #    project_urn: URN of project to update
    718 #    Options: Contains ‘fields’ key referencing dictionary of key/value pairs to update project
    719 #
    720 # Return: None
    721 def update_project(project_urn, credentials, options)
    722 }}}
    723 
    724 == Project Member Service Methods ==
    725 
    726 Projects may have members associated with them in particular roles. See the Slice Member Service Methods above for more description.
    727 
    728 {{{
    729 #!python
    730 # Modify project membership, adding, removing and changing roles of members with respect to given project
    731 #
    732 # Arguments:
    733 #   project_urn: Name of project for which to modify membership
    734 #   Options:
    735 #      members_to_add: List of member_urn/role tuples for members to add to project of form {‘PROJECT_MEMBER’: member_urn, ‘PROJECT_ROLE’ : role}
    736 #      members_to_remove: List of member_urn of members to remove from project
    737 #      members_to_change: List of member_urn/role tuples for members whose role should change as specified for given project of form {‘PROJECT_MEMBER’ : member_urn, ‘PROJECT_ROLE’ : role}
    738 #
    739 # Return:  None
    740 def modify_project_membership(project_urn, credentials, options)
    741 }}}
    742 
    743 {{{
    744 #!python
    745 # Lookup members of given project and their roles within that project
    746 #
    747 # Arguments:
    748 #    project_urn: project_urn for which to provide current members and roles
    749 #
    750 #Return:
    751 #   List of dictionaries of member_urn/role pairs of form [{‘PROJECT_MEMBER’: member_urn, ‘PROJECT_ROLE’: role}...]
    752 def lookup_project_members (project_urn, credentials, options)
    753 }}}
    754 
    755 {{{
    756 #!python
    757 # Lookup projects for which the given member belongs
    758 #
    759 # Arguments:
    760 #    Member_urn: The member for whom to find project to which it belongs
    761 #
    762 # Return:
    763 #    Dictionary of slice_urn/role pairs (‘PROJECT_URN’ : project_urn, ‘PROJECT_ROLE’ : role} where role is a string of the role name
    764 def lookup_projects_for_member(member_urn, credentials, options)
    765 }}}
    766 
    767 == Member Authority API ==
    768 
    769 The Member Authority API provides services to manage information about federation members including public and potentially private or identifying information.
    770 
    771 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.
    772 
    773 All MA calls are protected; passing and validating a client-side cert is required.
    774 
    775  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:
    776 
    777  * The user/tool cert is signed by someone in the Federation's trust chain
    778  * 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.
    779  * 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.
    780  * Access to private info (SSL or SSH keys) should be restricted only to the user’s own keys for ordinary users.
    781 
    782 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:
    783 
    784 || '''Service''' || '''Description''' || '''Required''' || '''Object'''
    785 || MEMBER || Services to  lookup and update information about members || YES || MEMBER ||
    786 || KEY || Services to support storing, deleting and retrieving keys (e.g. SSH)  for members || NO || KEY ||
    787 
    788 == Member Service Methods ==
    789 
    790 The information managed by the MA API is divided into three categories, for purposes of applying different AuthZ policies at these different levels:
    791 
    792  * Public: Public information about a member (e.g. public SSH or SSH keys, speaks-for credentials, certificates)
    793  * 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
    794  * Identifying: Information that could identify the given member (e.g. name, email, affiliation)
    795 
    796 The following table contains required fields for member objects and whether they are allowed in lookup ‘match’ criteria and their protection (public, private, identifying):
    797 
    798 
    799 || ''' Name ''' || ''' Type ''' || ''' Description ''' || ''' Match ''' || ''' Protection ''' ||
    800 || MEMBER_URN || URN || URN of given member || Yes || Public ||
    801 || MEMBER_UID ||UID || UID (unique within authority) of member || Yes || Public ||
    802 || MEMBER_FIRSTNAME || STRING || First name of member || Yes || Identifying ||
    803 || MEMBER_LASTNAME || STRING || Last name of member || Yes || Identifying ||
    804 || MEMBER_USERNAME || STRING || Username of user || Yes || Public ||
    805 || MEMBER_EMAIL || STRING || Email of user || Yes || Identifying ||
    806 
    807 {{{
    808 #!python
    809 # Return information about version and options (filter, query, credential types) accepted by this member authority
    810 #
    811 # Arguments: None
    812 #
    813 # Return:
    814 #     get_version structure information as described above
    815 def get_version()
    816 }}}
    817 
    818 {{{
    819 #!python
    820 # Lookup public information about members matching given criteria
    821 #
    822 # Arguments:
    823 #   options: set of ‘filter’ and ‘match’ criteria specifying which members and which fields for each member to return
    824 #
    825 # Return:
    826 #   Dictionary indexed by member URN of dictionaries of name/value pairs of fields specified in ‘filter’ options for members matching ‘match’ criteria
    827 def lookup_public_member_info (credentials, options)
    828 }}}
    829 
    830 {{{
    831 #!python
    832 # Lookup private (SSL/SSH key) information about members matching given criteria
    833 #
    834 # Arguments:
    835 #    options: set of ‘filter’ and ‘match’ criteria specifying which members and which fields for each member to return
    836 #
    837 # Return:
    838 #    Dictionary indexed by member URN of name/value pairs of fields specified in ‘filter’ options for members matching ‘match’ criteria
    839 def lookup_private_member_info (credentials, options)
    840 }}}
    841 
    842 {{{
    843 #!python
    844 # Lookup identifying (e.g. name, email) info about matching members
    845 #
    846 # Arguments:
    847 #    options: set of ‘filter’ and ‘match’ criteria specifying which members and which fields for each member to return
    848 #
    849 # Return:
    850 #    Dictionary indexed by member URN of name/value pairs of fields specified in ‘filter’ options for members matching ‘match’ criteria
    851 def  lookup_identifying_member_info(credentials, options)
    852 }}}
    853 
    854 {{{
    855 #!python
    856 # Update information about given member public, private or identifying information
    857 #
    858 # Arguments:
    859 #    member_urn: URN of member for whom to set information
    860 #    options: Containing ‘update’ key with dictionary of name/value pairs to update info for given member
    861 #
    862 # Return: None
    863 def update_member_info(member_urn, credentials, options)
    864 }}}
    865 
    866 {{{
    867 #!python
    868 # Provide list of credentials (signed statements) for given member
    869 # This is member-specific information suitable for passing as credentials in an AM API call for aggregate authorization.
    870 # Arguments:
    871 #    member_urn: URN of member for which to retrieve credentials
    872 #    options: Potentially contains ‘speaking-for’ key indicating a speaks-for invocation (with certificate of the accountable member in the credentials argument)
    873 #
    874 # Return:
    875 #     List of credential in “CREDENTIALS” format, i.e. a list of credentials with type information suitable for passing to aggregates speaking AM API V3.
    876 def get_credentials(member_urn, credentials, options)
    877 }}}
    878 
    879 == Key Service Methods ==
    880 
    881 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.
    882 
    883 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:
    884 
    885 || '''Name''' || '''Type''' || '''Description''' || '''Match''' || '''Creation''' || '''Update''' ||
    886 || KEY_MEMBER || URN || URN of member associated with key pair || Yes || Required || No ||
    887 || KEY_ID || STRING || Unique identifier of key: typically a fingerprint or hash of public key || Yes || No || No ||
    888 || KEY_PUBLIC || KEY || Public key value || Yes || Required || No ||
    889 || KEY_PRIVATE || KEY || Private key value || Yes || Allowed || No ||
    890 || KEY_DESCRIPTION || STRING || Human readable description of key pair || Yes || Allowed || Yes ||
    891 
    892 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 information for which the requestor is not authorized should fail on, at least, a per row basis. That is, if one asks for KEY_PUBLIC and KEY_PRIVATE for a list of member_urn's, the key pair should be returned only for those members to whom access to BOTH halves of the key are allowed. Note also that storing the private key is optional: an empty private key returned from a lookup method is an indication that no such key is stored, not that the access to the private key is not authorized.
    893 
    894 {{{
    895 #!python
    896 # Create a record for a key pair for given member
    897 #
    898 # Arguments:
    899 #    options: 'fields' containing the fields for the key pair being stored
    900 #
    901 # Return:
    902 #    Dictionary of name/value pairs for created key record including the KEY_ID
    903 #
    904 # Should return DUPLICATE_ERROR if a key with the same KEY_ID is already stored for given user
    905 def create_key(credentials, options)
    906 }}}
    907 
    908 {{{
    909 #!python
    910 # Delete a key pair for given member
    911 #
    912 # Arguments:
    913 #    member_urn: urn of member for which to delete key pair
    914 #    key_id: KEY_ID (fingerprint) of key pair to be deleted
    915 #
    916 # Return:
    917 #    True if succeeded
    918 #
    919 # Should return ARGUMENT_ERROR if no such key is found for user
    920 def delete_key(member_urn, key_id, credentials, options)
    921 }}}
    922 
    923 {{{
    924 #!python
    925 # Update the details of a key pair for given member
    926 #
    927 # Arguments:
    928 #    member_urn: urn of member for which to delete key pair
    929 #    key_id: KEY_ID (fingerprint) of key pair to be deleted
    930 #    options: 'fields' containing fields for key pairs that are permitted for update
    931 #
    932 # Return:
    933 #    None
    934 #
    935 # Should return ARGUMENT_ERROR if no such key is found for user
    936 def update_key(member_urn, key_id, credentials, options)
    937 }}}
    938 
    939 {{{
    940 #!python
    941 # Lookup keys for given match criteria return fields in given filter criteria
    942 #
    943 # Arguments:
    944 #    options: 'match' for query match criteria, 'filter' for fields to be returned
    945 #
    946 # Return:
    947 #    Dictionary (indexed by member_urn) of dictionaries containing name/value pairs for all keys registered for that given user.
    948 def lookup_keys(credentials, options)
    949 }}}
    950 
    951 == Appendix: Federation Object Models ==
    952 
    953 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.
    954 
    955 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.
    956 
    957 The following diagram reflects the different objects maintained within the full range of Authority services, their interactions and mandatory fields.
    958 
    959 [[Image(FedObjectModel.pdf, 50%,nolink)]]
    960 
    961 == Appendix B: API Data Types ==
    962 
    963 The following table describes the data types referenced in the document above, in terms of format and meaning.
    964 
    965 || ''' Type ''' || ''' Description ''' || ''' Format ''' ||
    966 || 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) ||
    967 || 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. ||
    968 || STRING || Generic UTF-8 string ||  ||
    969 || INTEGER || Generic integer argument || ||
    970 || DATETIME || Date time in UTC format || '''Examples:''' 2013-06-15 02:39:08 2013-06-15 02:39:08-05:00 '''Details:''' Assumed in GMT time zone unless specified: '''GMT:''' YYYY-MM-DD HH:mm:ss '''Time zone offset specified:''' YYYY-MM-DD HH:mm:ss-HH:mm ||
    971 || EMAIL || Well-formed email address || '''Example:''' jbrown@geni.net ||
    972 || KEY || SSH or SSL public or private key (contents, not filename) || Key-specific format ||
    973 || BOOLEAN || True or False (case insensitive) || '''Example:''' True ||
    974 || 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> } ] ||
    975 || CERTIFICATE || X509 certificate (contents, not filename) || Standard X509 certificate format ||
    976 
    977 As noted above, this list is subject to change as the API develops over time.
     1= Common Federation API version 1 =
     2The [wiki:CommonFederationAPIv1 Common Federation API v1] page has moved. The new location is: http://groups.geni.net/geni/wiki/CommonFederationAPIv1