Our APIs are using OpenID Connect for authentication.
We use this because it provides a secure method of authentication and builds on the authorization system in OAuth 2.0.
We also provide a personal access token system as well. This better targets server-side script applications that can not easily utilize the interactive login we enforce by OpenID Connect + OAuth 2.0.
The personal access token system is slightly different from other applications in that the token you receive is a refresh token which has a long expiration time (90 days). Read more on how to obtain an access token from a personal access token refresh token.
For increased security, our APIs also support DPoP (Proof-of-Possession) , which binds access tokens to a client-held key to reduce token replay risk.
We recently switched to utilizing a JWT to wrap our token identifiers. This allows several benefits.
Hubstaff APIs support DPoP (RFC 9449) to prevent token replay attacks by binding an access token to a specific client key pair.
Send the proof as a signed JWT in the DPoP: <dpop_jwt> header.
The signed JWT proof includes the following request-specific claims:
128bytes.Authorization: Bearer <access_token>).dpop+jwt Generate an EC P-256 keypair.
Store the private key securely. Publish the public key via the
openssl ecparam -name prime256v1 -genkey -out private.pem
openssl ec -in private.pem -pubout -out public.pemBuild a JWT payload bound to the request:
{
"htm": "<HTTP_METHOD>", // e.g. "GET", "POST"
"htu": "<TARGET_URI>", // scheme + host + path (no query/fragment)
"iat": <unix_timestamp_seconds>, // must be recent
"jti": "<unique_id>" // max 128 bytes
// If access token is present:
// "ath": "<ath>"
}athbinds the DPoP to a specific access token:
ath = BASE64URL( SHA256( ASCII(access_token) ) ) // no "=" paddingAdd required JWT headers:
{
"typ": "dpop+jwt",
"alg": "ES256",
"jwk": <PUBLIC_KEY_AS_JWK>
}Sign the JWT using the private key (ES256) and send it as the DPoPheader:
DPoP: <signed_dpop_jwt>To start using our APIs in your product you need to first create an oauth app.
You will need the following pieces of identification information
Also you will need a Redirect URI. This is the URI that the user will be sent to after authorizing your app. We require you to pre-register your redirect URIs as we verify your authorization requests against it to prevent hijacking attempts. Redirect URIs should be a full URI and must be HTTPS except for local development using localhost or .test top-level domains.
This can be done by going to the oauth apps page and clicking New.
To perform an authentication request you must first request our Open ID Connect configuration from our discovery endpoint.
If you are using a Open ID Compliant client library you should simply need to perform a discovery against https://account.sandbox.hbstf.co
This will request the Open ID Connect Discovery configuration [ https://account.sandbox.hbstf.co/.well-known/openid-configuration ]
You should cache this information for 1 week. This configuration includes
To initiate an authorization request, redirect the user to the authorization_endpoint with the following information.
code for this as we only support the Authorization Code flow.openid, profile, email, and scopes for access within the specific API.S256transformation of the code_verifier as defined by the PKCE specification RFC 7636: code_verifier = high-entropy cryptographic random string (43–128 characters) consisting only of URL-safe characters (A–Z a–z 0–9 - . _ ~)Base64url encoding must be performed without without
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
= padding. S256 transformation. The user will be presented with an authorization screen by us showing them what data you are wanting access to. Once they authorize the request we will send them to the redirect_uri with the code and state
Once you receive a success response to your redirect_uri you use the code in that response to exchange for an access token.
This is done by making a POST to the token_endpoint to retrieve the access_token and refresh_token.
authorization_code for thisOn a successful response you will receive
bearer.To make an API request using the access_token you just need to send it in the Authorization header like this
Authorization: Bearer e2f8c8e136c73b1e909bb1021b3b4c29
If DPoP is enabled for your token, also include the DPoP header.
DPoP: <dpop_jwt> To refresh the access_token make a refresh grant request to the token_endpoint.
This is done by making a POST to the token_endpoint .
refresh_token for thisOn a successful response you will receive
bearer.Personal access tokens can be managed on the personal access token page.
When you create a personal access token you will receive a refresh token identifier. Before connecting to our API, you first need to exchange that for an access token. Exchanging the token is done by calling the standard OAuth 2.0 token endpoint and using the refresh_token grant_type.
This is done by making a POST to the token_endpoint .
Note that this is nearly identical to the standard refresh_token call
refresh_token for thisOn a successful response you will receive
bearer.