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.
Prerequisites
Section titled “Prerequisites”- Object Storage enabled in your project. For instructions, read Enable Object Storage.
- A running STACKIT Server (VM) and a STACKIT service account. For instructions on creating and connecting service accounts, read How to use Service Accounts via the IaaS-API and Attach a service account to a server.
curlandjqinstalled on the server.- For the advanced path:
- the AWS CLI configured for Object Storage. For instructions, read Set up the CLI client.
- the
object-storage.service-account.createpermission for the service account you plan to connect.
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:
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:
curl -s http://169.254.169.254/stackit/v1/service-accounts | jqThe 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:
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:
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$SA_MAIL | jqThe answer should look similar to this:
{ "Code": "Success", "AccessKeyId": "AF17TKP7BTQX4HSLOXBA", "SecretAccessKey": "abcABC123456789012345678901234567890abcA", "Token": "eyJhbGciOiValidToken...", "Expiration": "2026-07-07T10:30:00Z"}Use AccessKeyId, SecretAccessKey to authenticate S3 requests from the workload. The ‘Token’ field is currently not in use but preserved for future use. The validity period for the credentials is 48 hours upon creation. The Expiration field indicates when the credentials expire. The expiration period of 48 hours cannot be configured, and the credentials cannot be renewed. To continue using Object Storage after the credentials expire, request new credentials from the metadata API. We recommend renewing the credentials every 24 hours, retries to the credential endpoint should not be made faster as one per minute until the request succeeds.
Pre-provision the mapping and bucket policy
Section titled “Pre-provision the mapping and bucket policy”In order to access the Object Storage bucket, create the service account mapping and apply a bucket policy before you call the short-lived object storage token endpoint.
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.
-
Connect the service account to the server:
Terminal window stackit server service-account attach <SERVICE_ACCOUNT_MAIL>@sa.stackit.cloud --server-id <SERVER_ID> -
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') -
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 \| jqThe 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.
-
Use the returned
urnas thePrincipalin 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.
To learn more about writing policy statements, read Manage bucket policies. To manage static credentials instead of temporary ones, read Create and delete credentials.