[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[[["\u003cp\u003eGoogle Distributed Cloud air-gapped appliance utilizes software-defined object storage with a unique user management system.\u003c/p\u003e\n"],["\u003cp\u003eObject storage user credentials, including access and secret keys, are stored as secrets within Kubernetes clusters.\u003c/p\u003e\n"],["\u003cp\u003eRotating object storage user credentials is required for regularly scheduled key rotations and for mitigating key exposure.\u003c/p\u003e\n"],["\u003cp\u003eRotating the keys involves updating all the secrets in the system.\u003c/p\u003e\n"]]],[],null,["# Rotate object storage credentials\n\nGoogle Distributed Cloud (GDC) air-gapped appliance object storage is provided by OTS (ONTAP Select). OTS has its own object\nstorage user management system. Each `OTS` object storage user credentials is stored as a secret in clusters.\n\nThis document describes the steps to rotate `OTS` object storage user credentials. Rotate object storage user credentials in the following situations:\n\n- regularly scheduled key rotation to rotate all user keys.\n- mitigating key exposure. You should rotate the exposed user key as soon as possible.\n\nBefore you begin\n----------------\n\nComplete the following steps:\n\n1. Verify that you meet the [laptop prerequisites](/distributed-cloud/hosted/docs/latest/appliance/admin/laptop).\n2. Ensure that you can login to the OTS cluster and run `vserver object-store-server` CLI commands.\n3. Ensure that you can log as administrator into the infra cluster and management cluster using `kubectl`.\n\nTranslate UID\n-------------\n\nEach object storage user has an access key and secret key that are stored as a\nKubernetes secret and used by Kubernetes workloads to access the backend object\nstorage. Rotating the user keys includes updating all the secrets.\n\nYou can get a list of object storage users by signing into one of the three nodes using: \n\n vserver object-store-server user show\n\nThe output is a list of UIDs and should be similar to: \n\n [\n \"root\",\n \"k8ssa_gpc-system_inventory-export-images\",\n \"k8ssa_gpc-system_inventory-export-hardware\",\n \"k8su_test-user@example.com\"\n ]\n\nThere are three types of users:\n\nThe `root` user has three identical secrets, mirroring the structure of the Data\nCenter, which encompasses multiple storage classes and tenant categories. In\ncontrast, Appliance only has a single tier of object storage. *All three\nsecrets* associated with the root user must be rotated simultaneously.\n\nUser identification (UID), excluding the `root` user, should adhere to either\nthe `k8ssa_\u003cnamespace\u003e_\u003csa\u003e` or `k8su_\u003cusername\u003e` format. Obtain either the\n`\u003cencoded-sa\u003e` or `\u003cencoded-username\u003e`: \n\n echo -n '\u003cvar translate=\"no\"\u003eUID_SUFFIX\u003c/var\u003e' | shasum -a 256 | cut -d \" \" -f 1 | xxd -r -p | base32 | awk '{print tolower($0)}' | sed 's/=*$//g'\n\nReplace \u003cvar translate=\"no\"\u003eUID_SUFFIX\u003c/var\u003e with `\u003csa\u003e` in the UID, and\nyou will get `\u003cencoded-sa\u003e`.\n\nReplace \u003cvar translate=\"no\"\u003eUID_SUFFIX\u003c/var\u003e with `\u003cusername\u003e` in the UID,\nand you will get `\u003cencoded-username\u003e`.\n\nRotate user key\n---------------\n\n1. Login to the OTS cluster.\n\n2. Get a list of object storage user UIDs.\n\n vserver object-store-server user show\n\n The result is a list of UIDs. Examples can be found in [Translate UID](#translate-uid). Repeat the following steps for each UID in the list.\n3. Get the old access key and secret key for the target user.\n\n set -privilege advanced\n vserver object-store-server user show -user \u003cvar translate=\"no\"\u003eUID\u003c/var\u003e\n\n Replace \u003cvar translate=\"no\"\u003eUID\u003c/var\u003e with the target user UID.\n4. Generate a new access key and secret key for the target user in object storage.\n The old and new keys co-exist after this step, and both can be use for access.\n\n vserver object-store-server user regenerate-keys -vserver root-admin -user \u003cvar translate=\"no\"\u003eUID\u003c/var\u003e\n\n5. Update the Kubernetes secret with the new access key and secret key. You only need to update the secret in the root infra cluster or management cluster, and the secret is\n propagated to other clusters if needed.\n\n kubectl --kubeconfig \u003cvar translate=\"no\"\u003eKUBECONFIG\u003c/var\u003e patch secret -n \u003cvar translate=\"no\"\u003eSECRET_NAMESPACE\u003c/var\u003e \u003cvar translate=\"no\"\u003eSECRET_NAME\u003c/var\u003e --type='json' -p='[{\"op\": \"replace\", \"path\": \"/data/access-key-id\", \"value\": \"'\"$(echo -n \"\u003cvar translate=\"no\"\u003eACCESS_KEY\u003c/var\u003e\" | base64)\"'\"}, {\"op\": \"replace\", \"path\": \"/data/secret-access-key\", \"value\": \"'\"$(echo -n \"\u003cvar translate=\"no\"\u003eACCESS_KEY\u003c/var\u003e\" | base64)\"'\"}]'\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003eKUBECONFIG\u003c/var\u003e: the path to the kubeconfig. The API server must be the control plane API server for the `root` user; if not, it must be the management API server.\n - \u003cvar translate=\"no\"\u003eSECRET_NAME\u003c/var\u003e: the secret name for the user, which can be derived from the [Translate UID](#translate-uid) section. If the user has multiple Kubernetes secrets (i.e., `root` user), replace with each secret name and run the command.\n - \u003cvar translate=\"no\"\u003eSECRET_NAMESPACE\u003c/var\u003e: the secret namespace for user, which can be derived from the [Translate UID](#translate-uid) section.\n - \u003cvar translate=\"no\"\u003eACCESS_KEY\u003c/var\u003e: the new access key generated in the previous step.\n - \u003cvar translate=\"no\"\u003eSECRET_KEY\u003c/var\u003e: the new secret key generated in the previous step.\n6. The workload that consumes the secret must be implemented to refresh automatically. If not, you must restart the workload\n to reflect the change in the secret.\n\n For example, for `root` user, you need to restart the following workloads in the infra cluster: \n\n kubectl --kubeconfig \u003cvar translate=\"no\"\u003eKUBECONFIG\u003c/var\u003e rollout restart deployment obj-bucket-cm-backend-controller -n obj-system\n\nValidation\n----------\n\nFollow the Object Storage\n[create bucket](/distributed-cloud/hosted/docs/latest/appliance/platform/pa-user/create-storage-buckets) and\n[upload and download object](/distributed-cloud/hosted/docs/latest/appliance/platform/pa-user/upload-download-storage-objects)\nto create a new bucket and grant access using RBAC. The object storage key\nrotation is complete if the bucket is successfully created and the subject has\nthe necessary permissions to access it."]]