Skip to content

Local sign-in and 2FA

The sign-in authenticates the operator with an OAuth 2.0 form (password grant) and returns a Bearer token. When two-factor authentication (2FA) is enabled, the API asks for a TOTP code before delivering the token.

    sequenceDiagram
    participant C as Client
    participant A as Riversoft STCP Gemini API
    C->>A: POST /oauth/v2/token (grant_type, username, password)
    alt 2FA disabled
        A-->>C: 200 OK + access_token
    else 2FA enabled, TOTP registered
        A-->>C: 200 OK + challenge URL
        C->>A: POST challenge URL (Code)
        A-->>C: 200 OK + access_token
    else 2FA enabled, first access
        A-->>C: 200 OK + challenge URL + secret + qrcode
        Note over C: The operator adds the account in the authenticator app
        C->>A: POST challenge URL (Code)
        A-->>C: 200 OK + access_token
    end
  

Sign in

Send the operator credentials in an application/x-www-form-urlencoded form:

read -r -p 'Operator: ' API_USER
read -r -s -p 'Password: ' API_PASSWORD; printf '\n'

curl -s \
  --data-urlencode 'grant_type=password' \
  --data-urlencode "username=$API_USER" \
  --data-urlencode "password=$API_PASSWORD" \
  "$API_BASE/oauth/v2/token"

The Content-Type header must be exactly application/x-www-form-urlencoded, without charset. With another value, the API responds 415.

Sign-in with LDAP

To sign in with a corporate directory account, send the user in the <provider>/<operator> format. <provider> is the name of the LDAP provider in the API registration (ssoProviders):

curl -s \
  --data-urlencode 'grant_type=password' \
  --data-urlencode 'username=corporate-directory/jsmith' \
  --data-urlencode "password=$API_PASSWORD" \
  "$API_BASE/oauth/v2/token"

The operator must exist in Riversoft STCP Gemini API with the same name. LDAP is only accepted at /oauth/v2/token.

Response without 2FA

When 2FA is disabled, the API responds 200 with the token:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "scope": "{\"stcpcore\":{\"instance\":15,\"user\":15,...}}",
  "operator": "stcpadmin",
  "rest_name": "RestAPI",
  "token_type": "Bearer"
}
FieldDescription
access_tokenToken used in the following calls.
scopeOperator permissions on each resource group (JSON serialized as text).
operatorAuthenticated operator.
rest_nameAPI registration name (rest_name in config.json).
token_typeAlways Bearer.

See how to use the token in Session and logout.

Complete 2FA

2FA is enabled in the API registration (API/Supervision), in the enable2FA field, or by the DIRLMFA environment variable (see the API parameters). When it is enabled, the sign-in responds 200 with the challenge path instead of the token. The response has no status field: the fields present indicate the step.

Fields in the responseSituationWhat to do
access_token2FA disabled.Continue with the token.
URLTOTP already registered.Ask for the authenticator app code.
URL, secret and qrcodeFirst access: TOTP not registered yet.Show the QR code for registration and ask for the first code.

Answer the challenge

{
  "URL": "/oauth/v2/token/mfa/01936b2e-7c4a-7d1e-9f3a-2b5c8d9e0f12"
}

Send the 6-digit TOTP code in JSON to the path received in URL:

export MFA_PATH='<URL received at sign-in>'
read -r -s -p 'TOTP code: ' MFA_CODE; printf '\n'

curl -s -X POST \
  -H 'Content-Type: application/json' \
  -d "{\"Code\": \"$MFA_CODE\"}" \
  "$API_BASE$MFA_PATH"

With a valid code, the API responds 200 with the token, in the same format as the response without 2FA. The Operator body field is optional: the API uses the challenge operator.

Register TOTP (first access)

On the first sign-in with 2FA enabled, the API generates a TOTP secret for the operator and returns it with the challenge path:

{
  "URL": "/oauth/v2/token/mfa/01936b2e-7c4a-7d1e-9f3a-2b5c8d9e0f12",
  "secret": "<TOTP secret in Base32>",
  "qrcode": "<PNG image in Base64>"
}
FieldUse
secretTOTP secret, to type in the app when the QR code cannot be read.
qrcode200 × 200 pixel PNG image with the secret’s QR code, in standard Base64. In the app, the account appears as <rest_name> (Riversoft Config API), with the operator name.

To show the QR code, use the value directly in a data: URL:

image.src = `data:image/png;base64,${response.qrcode}`;

Registration follows these steps:

  1. Show the QR code and the secret and ask the operator to add the account in the authenticator app (Microsoft Authenticator, Google Authenticator or another TOTP-compatible app).
  2. Ask for the 6-digit code generated by the app and send it to the path received in URL, as in Answer the challenge.
  3. With a valid code, the API responds 200 with the token. The sign-in is complete; in the next sign-ins, the response brings only URL.

Important

The secret is stored in the first step. If the operator does not complete the first sign-in, the QR code is not shown again. In that case, an operator with the stcpadminsvc.main_oper_reset_pwd permission must reset 2FA at POST /stcpadminsvc/v2/supervision/stcpauth/reset/operator/2fa (see Management resources). A new secret is generated at the next sign-in.

Errors

HTTPSituation
400grant_type other than password, missing username or password, or empty body. In the challenge: empty body, invalid JSON or Content-Type other than application/json.
401Credentials not accepted, operator locked (Operator is locked, contact your system administrator), invalid code (Invalid code) or nonexistent challenge (You need to authenticate first at /oauth/token).
415Content-Type other than application/x-www-form-urlencoded at sign-in.
500Internal error.

Errors are returned in JSON, with error and error_description.

Warning

The challenge accepts three wrong codes. On the fourth, the operator is locked and the challenge discarded: an operator with permission must unlock it. The TOTP secret is sensitive data: show it only to the operator and do not write it to logs.

Next steps