Skip to content

Use service accounts via the metadata API for Object Storage

Last updated on

By the end of this tutorial, a workload on a STACKIT server obtains temporary S3 credentials for Object Storage through the server metadata API, without storing long-lived credentials on the machine. You also learn how to pre-provision a service account mapping and bucket policy so access is scoped from the moment the service account is linked.

Connect the service account and list it from the server

Section titled “Connect the service account and list it from the server”

Connect the service account to your server so it becomes available inside the VM. Run the following command, replacing <SERVICE_ACCOUNT_MAIL> and <SERVER_ID> with your values:

Terminal window
stackit server service-account attach <SERVICE_ACCOUNT_MAIL>@sa.stackit.cloud --server-id <SERVER_ID>

On the server, list the connected service accounts through the metadata API. The metadata API is reachable only from within the server at the well-known address http://169.254.169.254:

Terminal window
curl -s http://169.254.169.254/stackit/v1/service-accounts | jq

The answer should look similar to this:

{
"serviceAccountMails": ["my-service-account@sa.stackit.cloud"]
}

Get the S3 credentials from the metadata API

Section titled “Get the S3 credentials from the metadata API”

The metadata API exposes temporary S3 credentials for the connected service account. First, store the service account mail in a variable:

Terminal window
SA_MAIL=$(curl -s http://169.254.169.254/stackit/v1/service-accounts | jq -r '.serviceAccountMails[0]')

Then request the S3 credentials for that service account:

Terminal window
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$SA_MAIL | jq

The answer should look similar to this:

{
"Code": "Success",
"AccessKeyId": "AF17TKP7BTQX4HSLOXBA",
"SecretAccessKey": "abcABC123456789012345678901234567890abcA",
"Token": "eyJhbGciOiValidToken...",
"Expiration": "2026-07-07T10:30:00Z"
}

Use AccessKeyId, SecretAccessKey, and Token to authenticate S3 requests from the workload.

Pre-provision the mapping and bucket policy

Section titled “Pre-provision the mapping and bucket policy”

To avoid a window of unrestricted access, create the service account mapping and apply a bucket policy before you connect the service account to the server. When you create the mapping through the Object Storage API, you receive a URN that identifies the service account. Use that URN as the Principal in a bucket policy.

  1. On a machine with the STACKIT CLI, create a short-lived token for the service account you plan to connect. For a server-based token, retrieve it from the metadata API as shown in How to use Service Accounts via the IaaS-API:

    Terminal window
    TOKEN=$(curl -s http://169.254.169.254/stackit/v1/service-accounts/$SA_MAIL/token | jq -r '.token')
  2. Call the Object Storage create service account operation with the token to create the mapping and receive its URN. Replace <PROJECT_ID> with your project ID:

    Terminal window
    curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    https://object-storage.api.eu01.stackit.cloud/v1/project/<PROJECT_ID>/service-account \
    | jq

    The answer should look similar to this:

    {
    "project": "cd5e788d-5b7b-4ab9-a20d-e790205df10b",
    "urn": "urn:sgws:identity::12345678901234567890:user/my-service-account"
    }

    To learn more about this operation, read the API reference.

  3. Use the returned urn as the Principal in a bucket policy that grants only the access the workload needs. The following policy allows the service account to read and write objects in a single bucket:

    {
    "Statement": [
    {
    "Sid": "AllowServiceAccountAccess",
    "Effect": "Allow",
    "Principal": {
    "AWS": "urn:sgws:identity::12345678901234567890:user/my-service-account"
    },
    "Action": ["s3:GetObject", "s3:PutObject"],
    "Resource": "urn:sgws:s3:::my-super-bucket/*"
    }
    ]
    }

    Apply the policy to your bucket. For instructions, read Manage bucket policies.

  4. Connect the service account to the server. Because the bucket policy is already in place, access is scoped as soon as the service account becomes available on the server:

    Terminal window
    stackit server service-account attach <SERVICE_ACCOUNT_MAIL>@sa.stackit.cloud --server-id <SERVER_ID>

To learn more about writing policy statements, read Manage bucket policies. To manage static credentials instead of temporary ones, read Create and delete credentials.