OVHcloudOAuth2 and IAM setup
OAuth2 and IAM setup
Create an OAuth2 service account for s3ctl and grant it access to your Public Cloud project.
Applies to v0.8.38stable, released 4 November 2026Release notes →
s3ctl works best with an OAuth2 service account: create it, grant it an IAM policy on the Public Cloud project, and put its client ID and secret in your config. When it then runs, s3ctl creates a bucket-dedicated Public Cloud user and the container, attaches the user with the container policy role, imports the bucket-scoped S3 user policy, creates the S3 key, and returns the endpoint, region and credentials.
Create the service account
Section titled “Create the service account”The official ovhcloud CLI is the cleanest route. Install it from
OVHcloud’s getting started guide,
with Homebrew:
brew install --cask ovh/tap/ovhcloud-clior without it:
curl -fsSL https://raw.githubusercontent.com/ovh/ovhcloud-cli/main/install.sh | shSign in, then create the credentials:
ovhcloud loginovhcloud account api oauth2 client create \ --name "s3ctl" \ --description "s3ctl bucket provisioning" \ --flow "CLIENT_CREDENTIALS"OVHcloud returns a clientId and clientSecret. Use them as ovh_client_id and
ovh_client_secret in your s3ctl config.
You can also create the client in the API console for your account’s region
(EU,
CA,
US): open POST /me/api/oauth2/client
and submit:
{ "callbackUrls": [], "flow": "CLIENT_CREDENTIALS", "name": "s3ctl", "description": "s3ctl bucket provisioning"}Grant it access to the project
Section titled “Grant it access to the project”The service account can’t grant access to itself. Use the account’s admin user, or another identity with IAM administration rights. In OVHcloud Manager:
-
Open Identity, Security & Operations, then Policies.
-
Create a policy named
s3ctl-object-storage. -
Under Identities, select the
s3ctlservice account. -
Under Product types, select Public Cloud Project.
-
Under Resources, select the project’s long ID, shown under its name, for example
51ab2732562648349de40f72ac51c1c8. Use the same value asovh_service_name, not the display name. -
For the first smoke test, allow all actions on that project. Once it works, tighten the policy to the actions below.
The least-privilege actions for s3ctl are:
publicCloudProject:apiovh:getpublicCloudProject:apiovh:user/createpublicCloudProject:apiovh:user/deletepublicCloudProject:apiovh:user/getpublicCloudProject:apiovh:user/policy/createpublicCloudProject:apiovh:user/s3Credentials/createpublicCloudProject:apiovh:user/s3Credentials/deletepublicCloudProject:apiovh:user/s3Credentials/getpublicCloudProject:apiovh:region/storage/createpublicCloudProject:apiovh:region/storage/deletepublicCloudProject:apiovh:region/storage/editpublicCloudProject:apiovh:region/storage/getpublicCloudProject:apiovh:region/storage/policy/createTo create the policy through the API instead, start from
examples/ovh/ovh-iam-policy.json
and send it to POST /iam/policy. Get the service account’s identity URN from
GET /me/api/oauth2/client/{clientId}. OVHcloud documents its format as:
urn:v1:<eu|ca>:identity:credential:<account-id>/oauth2-<clientId>Get the project’s resource URN from GET /iam/resource, picking the publicCloudProject resource
that matches your project ID.
Check it before running s3ctl
Section titled “Check it before running s3ctl”With the same OAuth2 credentials, GET /cloud/project should list the project:
token="$(curl -fsS \ -d grant_type=client_credentials \ --data-urlencode "client_id=$OVH_CLIENT_ID" \ --data-urlencode "client_secret=$OVH_CLIENT_SECRET" \ -d scope=all \ https://www.ovh.com/auth/oauth2/token | jq -r .access_token)"
curl -fsS -H "Authorization: Bearer $token" \ https://eu.api.ovh.com/1.0/cloud/project | jq .[ "51ab2732562648349de40f72ac51c1c8"]Classic API credentials
Section titled “Classic API credentials”The application key, application secret and consumer key flow is OVHcloud’s classic API authentication, and s3ctl supports it directly. OVHcloud’s token page for your region pre-fills the rights s3ctl needs for Public Cloud buckets: EU, CA, US.
Put the returned values in ovh_application_key, ovh_application_secret and ovh_consumer_key.
Those pages don’t create OAuth2 credentials; for ovh_client_id and ovh_client_secret, use
POST /me/api/oauth2/client as above.