Cluster API
The Cluster API provides remote access to the OpenSVC cluster management and monitoring functionality. It is accessible through the agent listener on any running cluster node.
Access and Network Resolution
The Cluster API URL (server name) can be configured to resolve to various network endpoints to ensure high availability and redundancy.
Possible Resolutions:
-
Single Floating IP
A single virtual IP (VIP) address, typically managed by a failover service like
system/svc/vip. This is the most common and robust approach. -
Multiple Floating IP Addresses
A set of VIPs for complex network routing or multi-site setups.
-
All Cluster Node IPs
Every physical or virtual IP address of all nodes in the cluster.
-
Subset of Cluster Node IPs
A selection of node IP addresses, often used in large clusters or specific network segments.
Authentication Methods
The agent listener supports several industry-standard authentication methods to secure access to the API.
Basic Authentication
- Mechanism: The client provides the username and password in the request header of every API call and the password is compared to the
passwordkey of thesystem/usr/<username>object. - Authorization: The RBAC grants are read from the
system/usr/<username>grantkey. - User Object: The
system/usr/<username>object must exist on the cluster.
X.509 Certificate Authentication
- Mechanism: Authentication is based on a client-side X.509 certificate.
- Trust: The certificate must be signed by one of the Certificate Authorities listed in the cluster
cakeyword,system/sec/caby default, and carry the TLS client authentication extended key usage. A certificate signed by any other authority is refused, whatever itscn. - Username: The username is derived from the Common Name (
cn) field of the client certificate. A certificate with an emptycnis refused. - Authorization: The RBAC grants are read from the
system/usr/<username>grantkey. - User Object: The
system/usr/<username>object must exist on the cluster.
JSON Web Token (JWT)
- Mechanism: Authentication is based on a JWT passed as a bearer token.
- Username: The username is derived from the
subtoken claim. - Authorization: The RBAC grants are derived from the
grantclaim of a token the cluster issued itself, or from theentitlementsclaim of a token issued by an OIDC server. - User Object: The
system/usr/<username>object does not need to exist on the cluster if the tokens are issued and managed by an external OpenID Connect (OIDC) server. - Issuance: A token is obtained from the
POST /api/auth/tokenendpoint, which accepts only the requests authenticated by the unix socket (a localomcommand) or by Basic Authentication. A request authenticated by a token or by a certificate is refused with403 not allowed to create token. A remote client therefore presents its password once to obtain a token, and asks for a refresh token at the same time if it needs to renew without presenting the password again. - Availability: This method was added in OpenSVC v3 agents.
Managing API Users
Using an OpenID server
The OpenID server will need to be configured to provide tokens with an
entitlements claim, holding the grant expressions this cluster is to give the
user. The claim is not named grant: that is the claim of the tokens the
cluster issues itself.
[listener]
openid_issuer = https://auth.mycorp.com/realms/clusters
openid_client_id = om3
The daemon reads <openid_issuer>/.well-known/openid-configuration to discover
the provider, and fetches the signing keys from the jwks_uri it advertises. A
token is accepted only if:
- Its
audclaim contains theopenid_client_idvalue. - Its
issclaim equals theissuervalue advertised by the discovery document, which is not necessarily theopenid_issuerurl used to reach it. - Its signature verifies against a key of the
jwks_urikey set, named by the tokenkidheader.
➡️ See Also
Creating Local Users (system/usr/)
Skip this step if you plan to use only OIDC-issued tokens for a user. Local user objects define the user’s cluster grants for Basic and X.509 authentication.
# Create a cluster-wide administrator user
om system/usr/root create --kw grant=root
# Create user `usr1` with
# `admin` rights on namespace `ns1`
# `guest` (read-only) rights on namespace `ns2`
om system/usr/usr1 create --kw grant="admin:ns1 guest:ns2"
Generating X.509 Certificates for Users
This step is only necessary if you require X.509 authentication for the user.
The certificate is named after the object and signed by the cluster
certificate authority, which is what the api expects of it. The cn and ca
keywords hold those two and rarely need to be set.
# Generate Certificate:
om system/usr/root certificate create
om system/usr/usr1 certificate create
# Download Keys (for client use):
om system/usr/usr1 key decode --name certificate_chain
om system/usr/usr1 key decode --name certificate
om system/usr/usr1 key decode --name private_key
These commands will print the PEM-encoded keys to standard output.
Testing the API
The API manifest (documentation) is exposed by a demonstration agent for reference.
A practical test using a JWT:
# Generate a Temporary Token:
$ TOKEN=$(sudo om daemon auth token --subject usr1 --duration 10m)
# Call the `whoami` Endpoint:
$ curl -o- -k -s -H "Authorization: Bearer $TOKEN" https://localhost:1215/api/auth/whoami
Example Output:
{"auth":"jwt","grant":{"guest":["ns2"], "admin": ["ns1"]},"name":"usr1","namespace":"system","raw_grant":"admin:ns1 guest:ns2"}
Configuring the Listener TLS Certificate
The agent listener requires a TLS certificate to accept remote connections securely.
Upon initial agent installation and daemon startup:
- A self-signed Certificate Authority (CA) is automatically created as
system/sec/ca. - A listener certificate, signed by this internal CA, is automatically created as
system/sec/cert.
The following steps are only required if you need to re-sign the internal CA or switch to an external PKI.
Option 1: Using the Internal PKI
The initial configuration is done automatically upon agent installation and daemon startup, creating:
- The CA certificate at
system/sec/ca. - The listener certificate at
system/sec/cert.
- Import a valid certificate in
system/sec/ca:om system/sec/ca key change --name certificate --from ~/$CLUSTERNAME.pem om system/sec/ca key change --name certificate_chain --from ~/$CLUSTERNAME.chain om system/sec/ca key change --name private_key --from ~/$CLUSTERNAME.key - Recreate the listener certificate:
om system/sec/cert certificate create
Option 2: Using an External PKI
-
Adjust the Listener Certificate Subject:
Only the
cnis strictly required by OpenSVC, but the signing certificate authority will surely require more.om system/sec/cert config update --set cn=vip.$CLUSTERNAME.mycorp \ --set alt_names="node1.$CLUSTERNAME.mycorp node2.$CLUSTERNAME.mycorp" \ --set c=FR \ --set o=MyCorp \ --set ou=Support \ --set l=Paris \ --set st=IDF \ --set email=support@mycorp -
Create the Listener Certificate Request:
om system/sec/cert certificate signing-request -
Perform External Signing: (This is an external procedure to be done with your PKI tool using the generated csr.)
-
Load the Signed Certificate:
om system/sec/cert key change --name certificate_chain --from ~/$CLUSTERNAME_crt_chain.pemThe certificate is always first, then the CA certificate chain.
-
Configure Certificate Revocation List (Optional):
om cluster config update --set cluster.crl=http://crl.mycorp -
Restart the Daemons
om daemon restart --node="*"
Option 3: A Public Certificate from an ACME Directory
system/sec/cert certifies the names the nodes reach each other by, which no
public authority certifies. A name of the cluster published on the internet,
as the name of its virtual address, can have a second certificate, which
browsers and remote clients trust, obtained and renewed from an ACME directory
like Let’s Encrypt. The listener presents it to the clients asking that name,
and system/sec/cert to the others.
-
Create the sec of the public certificate:
om system/sec/public create --kw cn=vip.mycorp.com --kw email=support@mycorp.com \ --kw acme.directory=letsencrypt-staging -
Have the listener present it, and answer its challenges:
om cluster set --kw listener.tls_secs=system/sec/public --kw listener.acme_port=80listener.tls_secslists the secs whose certificates the listener presents to the clients asking one of their names.listener.acme_porthas every node answer the http-01 challenges of these certificates in plain http, on a port the nodes must leave free for it,80being the one an ACME directory reads them from. The listener answers/.well-known/acme-challenge/<token>there, and nothing else. -
Obtain the certificate:
om system/sec/public certificate renewThe renewal stores the challenge token in the sec, which the daemon replicates, and waits for every node to answer it before the directory reads it. The name may resolve to any node, or to a virtual address that moves between them. Once issued, the listener presents the certificate from the next connection, on every node, without a restart.
-
Switch to the trusted directory once the staging certificate is in place, keeping the ACME keys of the sec, which record the directory its certificate comes from:
om system/sec/public set --kw acme.directory=letsencrypt om system/sec/public certificate renew -
Schedule the renewal, daily, from a cron of a node for example: it does nothing until the certificate expires within 30 days.
The http-01 challenge certifies a name, not a wildcard: a *.mycorp.com
certificate needs the dns challenge, which is not supported.
Certificates describes the renewal.
➡️ See Also
- Access Control for roles and grant management.