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".
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.
If you are running OA4MP, then this facility is configured on the server as per client management configuration.
You must register an administrative client as per 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
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.
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.
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. |
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.
The major versions are
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.
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.
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.)
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.
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
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). |
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.
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. |
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 | false | N | 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. |