Bramble as an OpenID Connect provider ("Sign in with Bramble"): discovery, keys, authorise and consent, token (authorisation code with PKCE, refresh token, device code), device authorisation for apps without a browser, and user info. See single sign-on.
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/.well-known/openid-configuration', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
None: public, or protected by a token in the address or body.
Response 200
Field
Type
Description
keys
array of any
Example response
JSON
{"keys":[]}
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/jwks.json', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
The authorisation endpoint. Send the person here with client_id, redirect_uri, response_type=code, scope, state and (recommended) code_challenge + code_challenge_method=S256. After sign-in and consent, Bramble redirects back with code and state.
None: public, or protected by a token in the address or body.
Query parameters
Name
Type
Description
client_idrequired
integer
redirect_urirequired
any
response_type
string
scoperequired
string
state
any
code_challengerequired
any
code_challenge_method
string
nonce
any
Response
A redirect, a file or page.
Errors
Status
Message
400
This app isn't set up correctly
400
This app isn't registered
400
This app has been disabled
403
Single sign-on is turned off
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/authorize?client_id=7&redirect_uri=%E2%80%A6&scope=string&code_challenge=%E2%80%A6', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
None: public, or protected by a token in the address or body.
Response 200
Field
Type
Description
clientName
string
scopes
array of any
Example response
JSON
{"clientName":"Example clientname","scopes":[]}
Errors
Status
Message
400
Consent request expired or missing
400
invalid_client
400
Consent request expired or invalid
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/consent-info', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
None: public, or protected by a token in the address or body.
Request body JSON
Name
Type
Description
decision
string
allow or deny.
Response
A body, a redirect.
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/consent', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"decision":"string"}),
});
const data = await res.json();
The token endpoint (form-encoded). grant_type is authorization_code (with code, redirect_uri, code_verifier), refresh_token (with refresh_token) or urn:ietf:params:oauth:grant-type:device_code (with device_code). Authenticate the app with client_id and client_secret. Returns access_token, id_token, expires_in and, where allowed, refresh_token.
None: public, or protected by a token in the address or body.
Request body JSON
Name
Type
Description
grant_type
string
Errors
Status
Message
400
invalid_client
401
invalid_client
403
access_denied
400
unsupported_grant_type
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/token', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"grant_type":"string"}),
});
const data = await res.json();
For apps without a browser. Returns a user_code to show and a verification_uri where the person enters it; then poll the token endpoint with the device_code.
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/device_authorization', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"scope":"…","device_name":"Example device name"}),
});
const data = await res.json();
#Under /oidc/ because BRM-Gateway proxies /oidc/* (and /auth/oidc/* on a tenant domain) on every host; a root /device isn't routed
GET/auth/oidc/device
Under /oidc/ because BRM-Gateway proxies /oidc/* (and /auth/oidc/* on a tenant domain) on every host; a root /device isn't routed. Signed-out visitors go to /auth/, which is the login page on every gateway host.
None: public, or protected by a token in the address or body.
Response
A redirect, a file or page.
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/device', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
That code isn't valid or has expired. Check the code on the device, or start again there.
403
Your account isn't allowed to use …. Ask your administrator.
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/device/info', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();
None: public, or protected by a token in the address or body.
Request body JSON
Name
Type
Description
user_code
any
decision
string
Response 200
Field
Type
Description
approved
any
Example response
JSON
{"approved":null}
Errors
Status
Message
415
Unsupported request
401
Sign in first.
404
That code isn't valid or has expired.
403
Your account isn't allowed to use ….
409
This request was already answered.
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/device/decision', {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({"user_code":"…","decision":"string"}),
});
const data = await res.json();
None: public, or protected by a token in the address or body.
Headers
authorization
Response 200
Errors
Status
Message
401
invalid_token
Example request
JavaScript
// From a page served by Bramble (uses the signed-in session)const res = awaitfetch('/auth/oidc/userinfo', {
method: 'GET',
credentials: 'include',
});
const data = await res.json();