API Server¶
Ralph comes with an API server that aims to implement the Learning Record Store (LRS) specification (still a work in progress).
Getting started¶
The API server supports the following authentication methods:
- Http Basic Authentication (default method)
- OpenID Connect authentication on top of OAuth2.0
HTTP Basic Authentication¶
The default method for securing Ralph API server is with HTTP basic authentication.
The API server can be started up with the following command:
$ ralph runserver --backend es
The --backend
(or -b
) option specifies which database backend to use for
LRS data storage and retrieval. See Ralph’s backends
documentation for more details.
However, before you can start your API server and make requests against it, you need to set up your credentials.
Creating a credentials file¶
The credentials file is expected to be a valid JSON file. Its location is
specified by the RALPH_AUTH_FILE
configuration value. By default, ralph
will look for the auth.json
file in the application directory (see click
documentation for
details).
The expected format is a list of entries (JSON objects) each containing the
username, the user’s bcrypt
hashed+salted password and scopes they can
access:
[
{
"username": "john.doe@example.com",
"hash": "$2b$12$yBXrzIuRIk6yaft5KUgVFOIPv0PskCCh9PXmF2t7pno.qUZ5LK0D2",
"scopes": ["example_scope"]
},
{
"username": "simon.says@example.com",
"hash": "$2b$12$yBXrzIuRIk6yaft5KUgVFOIPv0PskCCh9PXmF2t7pno.qUZ5LK0D2",
"scopes": ["second_scope", "third_scope"]
}
]
To create a new user credentials, Ralph’s CLI provides a dedicated command:
$ ralph auth \
--username janedoe \
--password supersecret \
--scope janedoe_scope \
-w
This command updates your credentials file with the new janedoe
user.
Note that running this command requires that you installed Ralph with the CLI optional dependencies, e.g.
pip install ralph-malph[cli]
(which we highly recommend).
Scopes¶
(Work In Progress)
Making a GET request¶
The first request that can be answered by the ralph API server is a whoami
request, which checks if the user is authenticated and returns their username and permission scopes.
Use curl to get http://localhost:8100/whoami
:
$ curl http://localhost:8100/whoami
< HTTP/1.1 401 Unauthorized
< {"error":"Not authenticated"}
Send your username and password to the API server through HTTP Basic Auth:
$ curl --user john.doe@example.com:PASSWORD http://localhost:8100/whoami
< HTTP/1.1 200 OK
< {"username":"john.doe@example.com","scopes":["authenticated","example_scope"]}
OpenID Connect authentication¶
Ralph LRS API server supports OpenID Connect (OIDC) on top of OAuth 2.0 for authentication and authorization.
To enable OIDC auth, you should set the RALPH_RUNSERVER_AUTH_BACKEND
environment variable as follows:
RALPH_RUNSERVER_AUTH_BACKEND=oidc
RALPH_RUNSERVER_AUTH_OIDC_ISSUER_URI
environment variable with your identity provider’s Issuer Identifier URI as follows:
RALPH_RUNSERVER_AUTH_OIDC_ISSUER_URI=http://{provider_host}:{provider_port}/auth/realms/{realm_name}
This address must be accessible to the LRS on startup as it will perform OIDC Discovery to retrieve public keys and other information about the OIDC environment.
It is also strongly recommended that you set the optional RALPH_RUNSERVER_AUTH_OIDC_AUDIENCE
environment variable to the origin address of the LRS itself (ex. “http://localhost:8100”) to enable verification that a given token was issued specifically for the LRS.
Identity Providers¶
OIDC support is currently developed and tested against Keycloak but may work with other identity providers that implement the specification.
The Learning analytics playground repository contains a Docker Compose file and configuration for a demo instance of Keycloak with a ralph
client.
Scopes¶
(Work In Progress)
Making a GET request¶
The first request that can be answered by the ralph API server is a whoami
request, which checks if the user is authenticated and returns their username and permission scopes.
Use curl to get http://localhost:8100/whoami
:
$ curl http://localhost:8100/whoami
< HTTP/1.1" 401 Unauthorized
< {"detail":"Could not validate credentials"}
curl --request POST 'http://localhost:8080/auth/realms/fun-mooc/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=ralph' \
--data-urlencode 'client_secret=super-secret' \
--data-urlencode 'username=ralph_admin' \
--data-urlencode 'password=funfunfun' \
--data-urlencode 'grant_type=password'
which outputs (tokens truncated for example purpose):
{
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJSTWlLM",
"expires_in":300,
"refresh_expires_in":1800,
"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4MDc5NjExM",
"token_type":"Bearer",
"not-before-policy":0,
"session_state":"22a36735-e35f-496b-a243-152d32ebff45",
"scope":"profile email"
}
Send the access token to the API server as a Bearer header:
$ curl http://localhost:8100/whoami --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJSTWlLM"
< HTTP/1.1 200 OK
< {"username":"ralph_admin","scopes":["all"]}
Forwarding statements¶
Ralph’s API server can be configured to forward xAPI statements it receives to other LRSes.
To configure statement forwarding, you need to create a .env
file in the current
directory and define the RALPH_XAPI_FORWARDINGS
variable or define the
RALPH_XAPI_FORWARDINGS
environment variable.
The value of the RALPH_XAPI_FORWARDINGS
variable should be a JSON encoded list of
dictionaries where each dictionary defines a forwarding configuration and consists of
the following key/value pairs:
key | value type | description |
---|---|---|
is_active |
boolean |
Specifies whether or not this forwarding configuration should take effect. |
url |
URL |
Specifies the endpoint URL where forwarded statements should be send. |
basic_username |
string |
Specifies the basic auth username. |
basic_password |
string |
Specifies the basic auth password. |
max_retries |
number |
Specifies the number of times a failed forwarding request should be retried. |
timeout |
number |
Specifies the duration in seconds of network inactivity leading to a timeout. |
Note that for a forwarding configuration to be valid it is required that all key/value pairs are defined.
Example of a valid forwarding configuration:
RALPH_XAPI_FORWARDINGS='
[
{
"is_active": true,
"url": "http://lrs1.example.com/xAPI/statements/",
"basic_username": "admin1@example.com",
"basic_password": "PASSWORD1",
"max_retries": 1,
"timeout": 5
},
{
"is_active": true,
"url": "http://lrs2.example.com/xAPI/statements/",
"basic_username": "admin2@example.com",
"basic_password": "PASSWORD2",
"max_retries": 5,
"timeout": 0.2
}
]
'
Sentry configuration¶
Ralph provides Sentry integration to monitor its LRS server and its CLI. To activate Sentry integration, one should define the following environment variables:
RALPH_SENTRY_DSN={PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}
RALPH_EXECUTION_ENVIRONMENT=development
The Sentry DSN (Data Source Name) can be found in your project settings from Sentry application. The execution environment should reflect the environment Ralph has been deployed in (e.g. production
).
You may also want to monitor the performance of Ralph by configuring the CLI and LRS traces sample rates:
RALPH_SENTRY_CLI_TRACES_SAMPLE_RATE=0.1
RALPH_SENTRY_LRS_TRACES_SAMPLE_RATE=0.3
Note that a sampling rate of
1.0
means 100% of transactions are sent to sentry and0.1
only 10%.
If you want to lower noisy transactions (e.g. in a Kubernetes cluster), you can disable health checks related ones:
RALPH_SENTRY_IGNORE_HEALTH_CHECKS=True
Additional configuration¶
HTTP Basic auth caching¶
HTTP basic auth implementation uses the secure and standard bcrypt algorithm to hash/salt passwords before storing them. This implementation comes with a performance cost. To speed up requests, credentials are stored in a LRU cache with a Time To Live. To configure this cache, you can define the following environment variables: - the maximum number of entries in the cache. Select a value greater than the maximum number of individual user credentials, for better performance. Defaults to 100.
RALPH_AUTH_CACHE_MAX_SIZE=100
RALPH_AUTH_CACHE_TTL=3600