Dynamic Client Registration

The dynamic client registration specification is supported in OA4MP as of version 4.2. This means that a trusted administrative client can dynamically create regular clients for use with an OA4MP system. If you have not done so already, you should read the section on administrative clients .

Note: When we refer to a client we mean an OAuth 2 client and otherwise any other will be qualified such as "admin client".

How's it work?

If you are not an administrator and just need a client, you can go to the registration endpoint of the service or use an anonymous registration (see below). Your request will then be seen by the site adminstrator(s) and once approved, you will be notified. OA4MP allows for an administration client that is trusted (after vetting, of course) who must manage several OAuth clients to do so without having to resort to the usual vetting process.

Looking for how to configure the server?

If you are running OA4MP, then this facility is configured on the server as per client management configuration.

How to become an admin

You must register an administrative client as per here.

Implemented specifications here.

The two specifications that are behind this are RFC 7591 and RFC 7592. The flow is that you register an administrative client. This is initially not approved and any operation you try will fail with a message to that effect. We get an notification and once the admin client is approved, it may be used. All calls then create regular (not admin!) clients for use with OA4MP.

The RFCs specify a REST-ful API for clients, so that

  • POST creates a new client
  • GET lists what the server knows about this client
  • PUT will update the client
  • DELETE will remove the client and all of its information from the server

Getting A List Of Clients

OA4MP does have one nice little extension for querying clients. If you do a GET with no client id, then a list of all client ids and names known to this admin will be returned.

Getting server defaults

You may also get defaults for the service by issuing a request with the query parameter set to org.oa4mp:/server#defaults. For instance on my local server

    curl -k --get --data-urlencode "query=org.oa4mp:/server#defaults"  https://localhost:9443/oauth2/oidc-cm
{
    "at_issuer":"https://localhost:9443/oauth2",
    "at_lifetime":900,
    "auth_grant_lifetime":750,
    "id_token_lifetime":900,
    "idt_max_lifetime":1800,
    "issuer":"https://localhost:9443/oauth2",
    "max_at_lifetime":1800,
    "max_id_token_lifetime":1800,
    "max_rt_lifetime":2592000,
    "rtGracePeriod":3600,
    "rt_lifetime":1296000,
    "rt_lifetime_create_default":-1,
    "rt_lifetime_update_default":0,
    "use_server_default":-1
}

where all time values are in seconds. The following table summarizes these. Note that if you have an admin client and send the credentials, the values for the issuer will reflect the values in the virtual organization. Otherwise, they are for the server generally. All lifetimes are in seconds. It is true that some of these are on the well-known page, however many are not and since there is no canonical way to represent them there, a separate call was created.

Valid values
Name Comments
api_versions List of API versions supported on this server. The first is "latest" and equals the second, E.g. ["latest","v5.5","v5.4"] means the maximum version is 5.5 and is a synonym with "latest". Note that "latest" will change with a server upgrade, so you can specify it and your clients will always use whatever the server has deployed. If you specify nothing, then the default is used.
api_version_default The default api version. If a client is created without specifying the version, this is used.
at_issuer The default access token issuer, used in access tokens that are JWTs.
at_lifetime The default access token lifetime for the server. If a client's at_lifetime is set to -1, this is used.
auth_grant_lifetime The default lifetime of authorization grants.
id_token_lifetime The default id token lifetime.
id_token_max_lifetime The server maximum id token lifetime. This is identical to max_id_token_lifetime.
issuer The default issuer asserted in id tokens.
max_at_lifetime The server's maximum allowed access token lifetime.
max_id_token_lifetime The server's maximum allowed id token lifetime.
max_rt_lifetime The server's maximum allowed refresh token lifetime.
rtGracePeriod The server's default grace period.
rt_lifetime The default refresh token lifetime. If a client's rt_lifetime is set to -1, this is used.
rt_lifetime_create_default If there is no rt_lifetime parameter asserted at client creation, use this.
rt_lifetime_update_default If there is no rt_lifetime parameter asserted at client update, use this.
use_server_default The value (usually -1) that means "use the server's default here". Typically when listing a client this will be the value for any lifetimes that were not explicitly set at creation.

Versions

Since OA4MP supports various attributes that are not standard, the response from the server for GET, PUT etc. can vary depending on the server version. The standard attributes are always faithefully reported in all versions, so the version simply refers to the OA4MP extensions reported. Note that if you query the server for its defaults, these are returned. Starting in OA4MP 5.5, this may be explicitly specified in one of two ways.

  • as an additional component in the URL path, so a path of https://myserver.org/oauth2/register/v5.5 would set the API version to 5.5.
  • as a query parameter with key api_version. If present, this overrides the path component. E.g. https://myserver.org/oauth2/register?api_version=v5.5...

The major versions are

  • v5.5 -- fully spec compliant and returns all values on the server, even those set as defaults. The aim is to expose more to clients so they can roundtrip more fully.
  • v5.4 -- limited values, in particular, rt_lifetime and at_lifetime are never allowed to be negative, but zero values for those are reported. (Negative -1 as a value means the client uses whatever the current server default is.)

The toolkit

Included with the latest release on GitHub are a suite of associated command line scripts in oidc-cm-scripts.tar aka the toolkit which contains a complete but minimal functional toolkit. There are basic scripts for each method as well as several examples for using each.

To dynamically register a client you need to make a call to the supported service endpoint, typically ../oauth2/oidc-cm with the appropriate HTTP method and payload. The specification should not be repeated here but the toolkit has a tutorial and many examples. There is also a very detailed readme.txt in the toolkit.

Parameters specific to OA4MP

OA4MP allows you to specify several client properties that it uses which are not in the specification. These are listed below in a table

Note that all of these are subject to server policies. You may request an outlandish refresh token lifetime, e.g., but if server policy restricts it, then the server will make the final determination.

Anonymous registration

An anonymous registration is simply creating a standard client without an associated admin client. In other words it is pretty much exactly like creating a basic client using the registration endpoint, although various OA4MP attributes are available that are not at the registration endpoint. This still restricts certain things you can configure, such as the cfg attribute. (Remember that an admin client has a vetted trust relationship with the server, so it has much wider latitude to create a standard client.)

Public clients

A public client is a standard client that is allowed only the user metadata openid scope (so not the org.cilogon.userinfo scope, e.g.). The primary function of a public client is to answer if the user has logged in to the system. If the client is anonymous, that is the only scope allowed. If the client is managed, it is possible the admin may allow other scopes for access tokens as well.

Legal Request Attributes

Standard attributes

Valid values
Parameter Required? Values Comments
callback_uri Y A JSON array of callback uris. You must have at least one callback uri. Note that the OAuth spec. requires that this be checked as a string against requests to the server that include it. No checking is done to resolve the address, so it is a bad idea to, e.g. have a raw IP address. By the same token, you can include parameters and such, but if they vary at all in the requests, then the request will be rejected. If you need to have some form of state management for each request, you should send the state parameter in the initial request. This is guaranteed to be returned to you unchanged as a parameter in the callback.
contacts N A list or string This should contain the valid email for a person to contact in case there is an issue with the client. You should assume that if you are going to be contacted at this address it will only be because of some dire issue. Supplying a generic institutional email is useless. The spec. allows for multiples but we only support a single (at this writing) so only the first will be used if a list is sent.
grant_type N Either a JSON array of blank delimited list which may contain
authorization_code (default),
refresh_token
urn:ietf:params:grant_type:token_exchange (for token exchange)
If omitted, the assumption is authorization_code. If you assert this grant, then the server default for refresh tokens is used. You may also specify a value using the OA4MP rt_lifetime parameter (see below). If you send rt_lifetime you do not need to assert the refresh token grant.
name Y The human-readable name for this client, to be displayed on the consent screen. Note that the RFC's do not require this, but OA4MP does.
response_type N code (default), id_token. Response types the client may support. If a requested response_type is not on this list, it should be rejected. Note that the initial request always must have the type "code." The others are used at other points and sent along in those requests, e.g. getting a refresh token requires you send "refresh_token" to the token endpoint.
scope N Either a JSON array or blank delimited list of scopes If you wish to use OIDC, you must at least supply a scope of openid. All supported scopes are
  • openid
  • email
  • profile
  • org.cilogon.userinfo
  • edu.uiuc.ncsa.myproxy.getcert
Note that the getcert scope requires you be able to get X509 certs via a MyProxy server, so only specify that if the service supports X509 certs and you really need it.
Public clients: Only openid scope is allowed and attempts to change the scopes will result in an error. It is not possible to change a public client to a confidential client. You must register a new client instead (This is due to our policies regarding creation of client secrets).

OA4MP specific attributes

In the table below are attributes that are specific to OA4MP and may be sent as well. In particular, note the Anon? column which if Y means than an anonymous client can set this.

Valid values
Parameter Required? Default Anon? Values Comments
at_lifetime N -1 Y Integer (in seconds) or unit This sets the access token lifetime for all subsequent access tokens. Note that is must be less than or equal to the server's default. You should only set this if you have a specific need for it an knowledge of what values will work. The default means to use the server default.
description N -- Y String This is an opaque string that contains a description of this client. It may or may not be human-readable, so "Jeff's test client" is fine as is "42-1455-35:4566-255" if that helps your admin client manage these.
ea_support N false N Boolean If this client accept extended attributes in requests. If false, then sending extended attributes simply strips them from the request and ignores.
ersatz_client N false N Boolean If this client can be used as an ersatz client.
extends_provisioners N false N Boolean The clients that provision this may be used as prototypes as well. Set this true if you want this (ersatz) client to inherit the settings of its provisioners. See ersatz clients for more.
cfg N -- Y JSON object This is a configuration that includes scripting for getting and processing additional claims. The admin client must have been approved to allow QDL if that will be used, otherwise only standard handlers may be configured. Generally you do not need to set this unless you have a very, very specific requirement. If you send attributes that do not fall within the spec., they will be put in this object for you. Generally if you do not know you need it and know what it does, you can safely ignore it.
Public clients:This parameter is not supported and will result in the rejection of any request.
forward_scopes_to_proxy N false N Boolean For servers that use a proxy to handle authorization, you may forward the scopes in the user's request to the proxy server. Generally this is not needed except in special cases and it overrides the proxy_request_scopes attribute. See using proxies for more information.
id_token_lifetime N -1 Y Integer (in seconds) or unit This sets the id token lifetime. Note that is must be less than or equal to the server's default. You should only set this if you have a specific need for it an knowledge of what values will work. The default of -1 means to use the server default.
is_service_client N false N Boolean If this client is to be a service client
max_at_lifetime N -1 Y Integer (in seconds) or unit This sets the maximum access token lifetime. This means that request may ask for a different lifetime than in the configuration, but it cannot exceed this. The server default is the absolute maximum.
max_id_token_lifetime N -1 Y Integer (in seconds) or unit This sets the maximum identity token lifetime. This means that request may ask for a different lifetime than in the configuration, but it cannot exceed this. The server default is the absolute maximum.
max_id_rt_lifetime N -1 Y Integer (in seconds) This sets the maximum refresh token lifetime. This means that request may ask for a different lifetime than in the configuration, but it cannot exceed this. The server default is the absolute maximum.
org.oa4mp:/client/status N approved N String This allows you to set the approval status of a client on update. The default when creating a client with an admin client is to approve it, but sometimes it is necessary to revoke it or set it to another status. Note that this must be explicitly sent to have an effect. Values are
  • approved - approved for all standard oeprations
  • denied - no approval, but the request was specifically denied for some reason
  • none - no particular status. The default when creating a client anonymously
  • pending - no approval, vetting of the client is underway but not resolved one way or the other.
  • revoked - no approval, for a previously approved client
Most of these are used for various stages of vetting clients that are registered over the web. Mostly dynamic registrations will use approved or revoked.
org.oa4mp:/ersatz/provisioners N -- N String, list of strings Passed in when creating or updating an ersatz client, this is the id of the provisioner. If there are multiples, an array of ids can be sent. See note here for more details.
prototypes N -- N List of client identifiers Any client may inherit the configuration of other clients. If set, then the list of client identifiers is used in sequence. See prototypes for more.
proxy_claims_list N -- N List of claims For servers that use a proxy to handle authorization. These are the claims from the proxy server that are to be asserted in the id token. See using proxies for more information.

Note that this is sent in the request to dynamic registration endpoint as a standard JSON array of strings
proxy_request_scopes N [*] N List of claims This is ignored if forward_scopes_to_proxy is set to true. For servers that use a proxy to handle authorization, there is a list of claims this client will request from the proxy server. The default is all claims, but you may restrict it to a subset (e.g. if the proxy server allows all claims but the current client is public, you may wish to restrict requests to the openid scope only.) Alternately, the client can simply use the claims in its request.

The default (*) means to send all configured scopes. Note that if this is empty, no scopes will be sent to the proxy server (quite possible in a basic OAuth 2 use case). If See using proxies for more information.

Note that this is sent in the request to dynamic registration endpoint as a standard JSON array of strings
rt_grace_period N -2 Y Integer (in seconds) or unit If you have enabled refresh tokens, this specifies the maximum grace period for token refreshes. That is to say, when a refresh token is refreshed or exchanged, the previous token remains active for this period of time. Setting this zero immediately invalidates the previous token. Specific values are 0 for disabled, -1 for disabling grace periods (equivalent to 0) or -2 to use whatever the server default is for grace periods.
rt_lifetime N -1 Y Integer (in seconds) or unit If you request a grant_type of refresh_token, this specifies the maximum lifetime, in seconds, that it will be valid. Normally this is set for a very long time, as in weeks if not months. If this is omitted then the server policy will be applied. This is typically using the server default refresh lifetime or perhaps disabling it. A value of 0 disables refresh tolens and a value of -1 means using whatever the server's default lifetime is.

Note the the server default lifetime is set in the client management configuration. The OA4MP default is -1, but CILogon's policy on creation/update is to disable refresh tokens unless explicitly granted, hence the default there is 0.
service_client_users N * N * or List If this is a service client, restrict the sub claim of requests to the token endpoint to what is on this list. If any sub is allowed, set this to *.
skip_server_scripts N false Y Boolean Servers may have system-wide scripts that are configured. Setting this true will skip those.
strict_scopes N true N true If set to true (default) only scopes explicitly set at registration will be allowed. Note that any unrecognized scopes in the initial request will cause the request to be rejected. If set to true you may send anything as a scope and allowed scopes will be processed, unknown scopes will be passed along for later processing and if not used, simply ignored. In the case that the access tokens is a JWT (such as SciTokens or WLCG tokens) set this false since the access token scopes would be passed in.