Developer Documentation

Everything you need to integrate rIDP into your applications

rIDP Base URL

All API endpoints use this base URL:

https://devas.ridp.ovh/v1

Getting Started

1. Create an Application

First, create a new application in this developer portal to get your OAuth credentials:

Create Application

2. Get Your Credentials

After creating your application, you'll receive:

  • Client ID - Public identifier for your application
  • Client Secret - Keep this confidential! Never expose it in client-side code.

3. Configure Your Redirect URI

When creating your application, you must specify the redirect URI(s) where users will be sent after authentication. This must exactly match the URI you use in your OAuth requests.

4. Available Scopes

Request the following scopes to access user information:

Scope Description
openid Required for OpenID Connect. Returns the user's unique identifier (sub).
profile Access to user's name and profile information.
email Access to user's email address.

5. Integrate in Your Application

Add a "Login with rIDP" button that redirects users to the authorization endpoint:

// Redirect user to rIDP authorization endpoint
const authUrl = `https://devas.ridp.ovh/v1/oauth/authorize?` +
  `response_type=code&` +
  `client_id=YOUR_CLIENT_ID&` +
  `redirect_uri=${encodeURIComponent('https://yourapp.com/callback')}&` +
  `scope=openid profile email&` +
  `state=${generateRandomState()}`;

window.location.href = authUrl;

OAuth 2.0 Authorization Flow

Authorization Code Flow

The most secure flow for web applications with server-side code.

  1. Redirect to Authorization Endpoint
    GET /authorize
  2. User Authenticates and Consents

    User logs in and approves your application's access request

  3. Receive Authorization Code

    User is redirected back with a temporary code

  4. Exchange Code for Tokens
    POST /token
  5. Use Access Token

    Make API calls with the access token

Security Note: Never expose your Client Secret in client-side code. For Single Page Applications, use PKCE (Proof Key for Code Exchange).

API Reference

Authorization Endpoint

GET /oauth/authorize

Initiates the OAuth 2.0 authorization flow.

Parameters:

Parameter Required Description
response_type Yes Must be "code"
client_id Yes Your application's client ID
redirect_uri Yes Registered callback URL
scope No Space-separated list of scopes
state Yes CSRF protection token (unguessable random string)
resource No Resource Indicators per RFC 8707 (array of URIs)

Token Endpoint

POST /oauth/token

Exchange authorization code for access tokens, or refresh an existing token.

Supported Grant Types:

  • authorization_code - Exchange authorization code for tokens
  • refresh_token - Get new access token using refresh token
  • password - Legacy, not recommended

Parameters:

Parameter Required Description
client_id Yes Your application's client ID
grant_type Yes "authorization_code", "refresh_token", or "password"
client_secret Conditional Required for confidential clients
code Conditional Required for authorization_code grant
redirect_uri Conditional Required for authorization_code grant (must match initial request)
refresh_token Conditional Required for refresh_token grant
username Conditional Required for password grant (legacy)
password Conditional Required for password grant (legacy)
scope No Space-separated scopes (must be subset of granted scopes)
resource No Resource Indicators per RFC 8707

Content-Type: Requests must use application/x-www-form-urlencoded

UserInfo Endpoint

GET /oauth/userinfo

Retrieve information about the authenticated user.

Note: rIDP currently implements a partial OIDC UserInfo endpoint for retrieving user information after OAuth2 authentication.

Headers:

Header Required Description
Authorization Yes Bearer {access_token} (must have "openid" scope)

Response (200 OK):

{
  "sub": "6d9e1f2a-3e3b-4eae-bf8a-9f8b6de51577",
  "email": "user@example.com"
}

Error Responses:

Status Error Description
401 invalid_token Access token is missing, invalid, or expired
403 insufficient_scope Access token lacks required "openid" scope

Code Examples

Express.js Example

import express from 'express';
import session from 'express-session';
import crypto from 'crypto';

const app = express();

// Configuration
const CLIENT_ID = 'your-client-id';
const CLIENT_SECRET = 'your-client-secret';
const REDIRECT_URI = 'https://yourapp.com/callback';
const IDP_BASE_URL = 'https://devas.ridp.ovh/v1';

app.use(session({
  secret: 'your-session-secret',
  resave: false,
  saveUninitialized: false
}));

// Step 1: Redirect to rIDP login
app.get('/login', (req, res) => {
  const state = crypto.randomUUID();
  req.session.oauth_state = state;

  const params = new URLSearchParams({
    response_type: 'code',
    client_id: CLIENT_ID,
    redirect_uri: REDIRECT_URI,
    scope: 'openid profile email',
    state: state
  });

  res.redirect(`${IDP_BASE_URL}/oauth/authorize?${params}`);
});

// Step 2: Handle callback
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;

  // Verify state matches
  if (state !== req.session.oauth_state) {
    return res.status(400).send('Invalid state');
  }

  // Exchange code for tokens
  const tokenResponse = await fetch(`${IDP_BASE_URL}/oauth/token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: code,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      redirect_uri: REDIRECT_URI
    })
  });

  const tokens = await tokenResponse.json();
  // tokens: { access_token, token_type, expires_in, refresh_token, scope }

  // Get user info
  const userResponse = await fetch(`${IDP_BASE_URL}/oauth/userinfo`, {
    headers: {
      'Authorization': `Bearer ${tokens.access_token}`
    }
  });

  const user = await userResponse.json();
  // user: { sub, email }

  req.session.user = user;
  res.redirect('/dashboard');
});

Flask Example

import secrets
from urllib.parse import urlencode

import requests
from flask import Flask, redirect, request, session

app = Flask(__name__)
app.secret_key = 'your-secret-key'

CLIENT_ID = 'your-client-id'
CLIENT_SECRET = 'your-client-secret'
REDIRECT_URI = 'http://localhost:5000/callback'
IDP_BASE_URL = 'https://devas.ridp.ovh/v1'

@app.route('/login')
def login():
    """Redirect user to rIDP for authentication"""
    state = secrets.token_urlsafe(32)
    session['oauth_state'] = state

    params = urlencode({
        'response_type': 'code',
        'client_id': CLIENT_ID,
        'redirect_uri': REDIRECT_URI,
        'scope': 'openid profile email',
        'state': state
    })
    return redirect(f"{IDP_BASE_URL}/oauth/authorize?{params}")

@app.route('/callback')
def callback():
    """Handle OAuth callback from rIDP"""
    # Verify state
    if request.args.get('state') != session.get('oauth_state'):
        return 'Invalid state', 400

    code = request.args.get('code')

    # Exchange code for tokens
    token_response = requests.post(
        f'{IDP_BASE_URL}/oauth/token',
        data={
            'grant_type': 'authorization_code',
            'code': code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI
        }
    )
    tokens = token_response.json()
    # tokens: { access_token, token_type, expires_in, refresh_token, scope }

    # Get user info
    user_response = requests.get(
        f'{IDP_BASE_URL}/oauth/userinfo',
        headers={'Authorization': f"Bearer {tokens['access_token']}"}
    )
    user = user_response.json()
    # user: { sub, email }

    session['user'] = user
    return redirect('/dashboard')

Step 1: Exchange Code for Token

curl -X POST https://devas.ridp.ovh/v1/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=YOUR_REDIRECT_URI"

# Response:
# {
#   "access_token": "eyJ...",
#   "token_type": "Bearer",
#   "expires_in": 3600,
#   "refresh_token": "...",
#   "scope": "openid profile email"
# }

Step 2: Get User Info

curl https://devas.ridp.ovh/v1/oauth/userinfo \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Response:
# {
#   "sub": "6d9e1f2a-3e3b-4eae-bf8a-9f8b6de51577",
#   "email": "user@example.com"
# }

Refresh Token

curl -X POST https://devas.ridp.ovh/v1/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=YOUR_REFRESH_TOKEN" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"