Detailed instructions for the Devolutions Server REST API are available in the API documentation section within the Devolutions Server web interface.
To connect and use the REST API, refer to the sample bash script below. For each API call to the server, ensure the following:
Replace
https://url
with the specific Devolutions Server URL.Replace
GUID-OF-VAULT
andGUID-OF-ENTRY
with the corresponding GUIDs.
In this version of the API, passwords can only be retrieved from entries of the Credentials type.
# Log in and get the token
authResponse=$(curl -s -X POST "https://url/api/v1/login" \
-H "Content-Type: application/json" \
-d '{
"appKey": "appkey",
"appSecret": "appsecret"
}')
token=$(echo $authResponse | jq -r '.tokenId')
# Check if the token was successfully obtained
if [ -z "$token" ] || [ "$token" = "null" ]; then
echo "Failed to login or obtain token."
exit 1
fi
# Request data using the token
response=$(curl -s -X GET "https://url/api/v1/vault/GUID-OF-VAULT/entry/GUID-OF-ENTRY" \
-H "Content-Type: application/json" \
-H "tokenId: $token")
echo $response | jq
# Log out
curl -s -X POST "https://url/api/v1/logout" \
-H "Content-Type: application/json" \
-H "tokenId: $token" \
-H "Content-Length: 0"
Devolutions Server supports Auth0’s device code authentication flow. Here are the steps to set this up:
Query the well-known OpenID configuration endpoint to retrieve the server’s token and device authorization endpoints:
try {
$wellKnownResponse = Invoke-RestMethod -Method Get -Uri $wellKnownEndpoint
$tokenEndpoint = $wellKnownResponse.token_endpoint
$deviceCodeEndpoint = $wellKnownResponse.device_authorization_endpoint
} catch {
Write-Error "Error obtaining server information"
exit
}
Send a request to the device authorization endpoint for a device code, a user code, a verification URL, and a complete verification URL, as well as details regarding how long the codes are valid and how often to check. Then, either open a browser to the complete verification URL, or direct the user to manually enter his or her user code and approve the device access request:
$body = "client_id=$clientId&scope=$([uri]::EscapeDataString($scope))"
try {
$deviceCodeResponse = Invoke-RestMethod -Method Post -Uri $deviceCodeEndpoint `
-ContentType "application/x-www-form-urlencoded" -Body $body
} catch {
Write-Error "Failed to obtain device code: $_"
exit
}
# Extract values from the response (field names may vary by provider)
$device_code = $deviceCodeResponse.device_code
$user_code = $deviceCodeResponse.user_code
$verification_uri = $deviceCodeResponse.verification_uri
$verification_uri_complete = $deviceCodeResponse.verification_uri_complete
$interval = 10 # in seconds
$expires_in = $deviceCodeResponse.expires_in # in seconds
# Provide a default interval if none was returned or if it's zero/null
if (-not $interval -or $interval -eq 0) {
$interval = 5
Write-Host "Interval not provided or invalid; defaulting to $interval seconds."
}
# Instead of instructing the user, open the browser to the verification_uri_complete
if ($verification_uri_complete) {
Write-Host "Opening browser for device authorization..."
Start-Process $verification_uri_complete
} else {
Write-Host "verification_uri_complete not provided. Please manually go to $verification_uri and enter the code: $user_code"
}
Start a loop that periodically sends a request to the token endpoint with the device code and client ID until the server returns an access token:
$startTime = Get-Date
$tokenResponse = $null
while (((Get-Date) - $startTime).TotalSeconds -lt $expires_in) {
Start-Sleep -Seconds $interval
try {# Build the POST body to exchange the device code for an access token
$tokenBody = "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=$clientId&device_code=$device_code"
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $tokenBody
if ($tokenResponse.access_token) {
Write-Host "Access token obtained:" $tokenResponse.access_token
break
}
}
catch {# Instead of reading the response content (which may be disposed), use the exception message.
$errorMessage = $_.Exception.Message
# Check if the exception message indicates that authorization is still pending.
if ($errorMessage -match "authorization_pending") {
Write-Host "Authorization pending..."
continue
}
else {
Write-Error "Error during token polling: $errorMessage"
break
}
}
}
if (-not $tokenResponse -or -not $tokenResponse.access_token) {
Write-Host "Failed to obtain an access token or authorization expired."
}
When needed, use the refresh (obtained during step #1) to request a new token from the token endpoint, ensuring continued access to the application:
$body = "grant_type=refresh_token&authorization=bearer $($tokenResponse.access_token)&refresh_token=$($tokenResponse.refresh_token)&client_id=dvls"
try {
$refreshResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $body
if ($refreshResponse.access_token) {
Write-Host "Access token obtained:" $tokenResponse.access_token
break
}
} catch {
Write-Error "Failed to obtain device code: $_"
exit
}