- Get the content of the QR for Okta Verify app setup. It looks like this:
oktaverify://[email protected]/?t=XXXXX&f=YYYYY&s=https://DOMAIN.okta.com&issuer=DOMAIN.okta.com&isIdxEnabled=true
- Replace
XXXXX
,YYYYY
andDOMAIN
to your values in curl below:
curl --request POST \
--url https://DOMAIN.okta.com/idp/authenticators \
--header 'Accept: application/json; charset=UTF-8' \
--header 'Accept-Encoding: gzip, deflate' \
--header 'Authorization: OTDT XXXXX' \
--header 'Content-Type: application/json; charset=UTF-8' \
--header 'User-Agent: D2DD7D3915.com.okta.android.auth/7.17.1 DeviceSDK/0.19.0 Android/13.1 unknown/Xiaomi' \
--data '{
"authenticatorId": "YYYYY",
"device": {
"clientInstanceBundleId": "com.okta.android.auth",
"clientInstanceDeviceSdkVersion": "DeviceSDK 0.19.0",
"clientInstanceVersion": "7.17.1",
"clientInstanceKey": {
"alg": "RS256",
"e": "AQAB\n",
"okta:isFipsCompliant": true,
"okta:kpr": "SOFTWARE",
"kty": "RSA",
"use": "sig",
"kid": "-e37YhNPIhjym6cHQBey0XlJfrcxKg31XjQ6hPRKQao",
"n": "vnvko4eUTu7FwUftRYI1ergvaWJ0NDbL8W2fvUWswBP7vYZOC21R4n18k7INLCfxHvfW0pQOY_jO3H1d_QXJJt1yRZUYkiQHV6yc1o14x_cfuS_5q6ZpKk_MbTik-kX1oebXlcj7MWP1I7E3TDsUAnsvwp0oP5K7eDN_QJYfaP0nrxQQaDFDKzJNv_jSucCSxO_aQoNNX-vyrUTxqvC9qfQ7rnC7hg5iXbJ-HWrX1494jGIfuDAm32-W5HlgZb0Q69IQevLbuI55BsCRPZwF-ef4zQgHV6N8KmDdpiOhXfAXoilf8w8dH1ccUIXX_sA9WQMVCc-llngS7LractTvQQ"
},
"deviceAttestation": {},
"displayName": "Bitwarden",
"fullDiskEncryption": false,
"isHardwareProtectionEnabled": false,
"manufacturer": "unknown",
"model": "Xiaomi",
"osVersion": "25",
"platform": "ANDROID",
"rootPrivileges": true,
"screenLock": false,
"secureHardwarePresent": false
},
"key": "okta_verify",
"methods": [
{
"isFipsCompliant": true,
"supportUserVerification": false,
"type": "totp"
}
]
}'
- Send this request and get
sharedSecret
value from the response. This is your TOTP secret key. Paste it to the corresponding app (e.g. Bitwarden) and enjoy!
- Example curl request:
curl --request POST \
--url https://state.okta.com/idp/authenticators \
--header 'Accept: application/json; charset=UTF-8' \
--header 'Accept-Encoding: gzip, deflate' \
--header 'Authorization: OTDT ftC9ysuejN2CYOHgbv19M9ysuwjsjySYAn4D' \
--header 'Content-Type: application/json; charset=UTF-8' \
--header 'User-Agent: D2DD7D3915.com.okta.android.auth/7.17.1 DeviceSDK/0.19.0 Android/13.1 unknown/Xiaomi' \
--data '{
"authenticatorId": "butlme8hf90eAYmyK537",
"device": {
"clientInstanceBundleId": "com.okta.android.auth",
"clientInstanceDeviceSdkVersion": "DeviceSDK 0.19.0",
"clientInstanceVersion": "7.17.1",
"clientInstanceKey": {
"alg": "RS256",
"e": "AQAB\n",
"okta:isFipsCompliant": true,
"okta:kpr": "SOFTWARE",
"kty": "RSA",
"use": "sig",
"kid": "-e37YhNPIhjym6cHQBey0XlJfrcxKg31XjQ6hPRKQao",
"n": "vnvko4eUTu7FwUftRYI1ergvaWJ0NDbL8W2fvUWswBP7vYZOC21R4n18k7INLCfxHvfW0pQOY_jO3H1d_QXJJt1yRZUYkiQHV6yc1o14x_cfuS_5q6ZpKk_MbTik-kX1oebXlcj7MWP1I7E3TDsUAnsvwp0oP5K7eDN_QJYfaP0nrxQQaDFDKzJNv_jSucCSxO_aQoNNX-vyrUTxqvC9qfQ7rnC7hg5iXbJ-HWrX1494jGIfuDAm32-W5HlgZb0Q69IQevLbuI55BsCRPZwF-ef4zQgHV6N8KmDdpiOhXfAXoilf8w8dH1ccUIXX_sA9WQMVCc-llngS7LractTvQQ"
},
"deviceAttestation": {},
"displayName": "Bitwarden",
"fullDiskEncryption": false,
"isHardwareProtectionEnabled": false,
"manufacturer": "unknown",
"model": "Xiaomi",
"osVersion": "25",
"platform": "ANDROID",
"rootPrivileges": true,
"screenLock": false,
"secureHardwarePresent": false
},
"key": "okta_verify",
"methods": [
{
"isFipsCompliant": true,
"supportUserVerification": false,
"type": "totp"
}
]
}'
- Example server response:
{"id":"pfdkd1fhmysksidj8eS297","authenticatorId":"ospwid8oaoaieiAYmyJ297","key":"okta_verify","status":"ACTIVE","type":"app","device":{"id":"guokdhorufsGaL1vVE297","status":"CREATED","created":"2023-07-30T16:56:19.000Z","lastUpdated":"2023-07-30T16:56:19.000Z","profile":{"displayName":"Bitwarden","platform":"ANDROID","manufacturer":"unknown","model":"Xiaomi","osVersion":"25","registered":true,"managed":false,"secureHardwarePresent":false},"_links":{"activate":{"href":"https://state.okta.com/api/v1/devices/gupaowiiehfsGaLkdido297/lifecycle/activate","hints":{"allow":["POST"]}},"self":{"href":"https://state.okta.com/api/v1/devices/guokmyauajwnslspwa7","hints":{"allow":["GET","PATCH","PUT"]}},"users":{"href":"https://state.okta.com/api/v1/devices/gupahuwoeprpodsjos7/users","hints":{"allow":["GET"]}}},"clientInstanceId":"cliososiejrbsjuiw7"},"user":{"id":"00kslsppwwjrjrurhnej297","username":"[email protected]"},"methods":[{"id":"oudjeoekeF2MOZGc297","type":"totp","createdDate":"2023-07-30T16:56:19.000Z","lastUpdated":"2023-07-30T16:56:19.000Z","sharedSecret":"YOUR_TOTP_SECRET_KEY_HERE"}],"createdDate":"2023-07-30T16:56:19.000Z","lastUpdated":"2023-07-30T16:56:19.000Z","_links":{"self":{"href":"https://state.okta.com/idp/authenticators/pospajehebrbsnksl97","hints":{"allow":["GET","DELETE"]}}}}
- All data in examples has been modified to garbage value.
Notes:
- This request creates a new device named "Bitwarden" in https://DOMAIN.okta.com/enduser/settings in "Security Methods" block
- If it returns invalid session error, probably your QR's content is expired
- If it returns 400 and complains to clientInstanceKey, try to replace
kid
andn
to values fromhttps://DOMAIN.okta.com/oauth2/v1/keys
Worked great in my case. Thank you very much.