오브젝트 잠금

오브젝트 잠금은 개별 오브젝트 버전이 WORM (Write-Once-Read-Many), 삭제 및 다시 쓰기 불가능 방식으로 저장되도록 하여 전자 레코드를 보존하고 데이터 무결성을 유지합니다. 이 정책은 지정된 날짜까지 또는 법적 보류가 제거될 때까지 적용됩니다.

오브젝트 잠금을 사용하는 이유

Object Lock을 사용하면 백업, 재해 복구 및 사이버 복원력 워크로드에 대해 데이터 불변성을 적용하여 데이터 보존 및 보존 요구사항을 관리할 수 있습니다.

오브젝트 잠금을 사용하면 데이터를 다른 사용자가 삭제할 수 없으며 오브젝트에 대한 보존을 일시중단할 방법이 없습니다. 보존 기간이 있는 오브젝트를 잠그기 전에 문서를 주의깊게 읽으십시오.

오브젝트 잠금을 사용하는 경우 장기 보존을 위해 데이터를 보존하고 저장할 때 사용자 (조직) 에게 적용될 수 있는 모든 규정을 준수하는지 확인하는 것은 사용자의 책임입니다.

Object Lock을 사용할 경우, 데이터가 보존 기간에 해당하는 동안 IBM Cloud 의 정책 및 지침에 따라 IBM Cloud 계정이 정상 상태를 유지하도록 할 책임은 귀하에게 있습니다. 자세한 정보는 IBM Cloud 서비스 이용 약관을 참조하십시오.

용어

오브젝트 잠금을 사용하여 데이터를 보호하는 두 가지 방법 ( 보존 기간증거보존 통지) 이 있습니다.

  • 보존 기간 은 오브젝트를 수정하거나 삭제할 수 없는 시간 프레임을 정의합니다.
  • 증거보존 통지 는 또한 오브젝트가 변경되는 것을 방지하지만 명시적으로 해제될 때까지만 제자리에 남아 있습니다.

이러한 매개변수의 조합을 사용할 수 있습니다. 오브젝트 버전은 하나 또는 둘 다 포함하거나 둘 다 포함하지 않을 수 있습니다.

보유 기한 날짜 (보유 기간)

고정된 시간 동안 오브젝트 버전을 보호해야 하는 경우 변경할 수 없는 기간을 판별하는 보유 종료 날짜 를 지정해야 합니다. 이 날짜가 지나면 오브젝트 버전을 삭제할 수 있습니다 (오브젝트 버전에 대한 법적 보류가 없다고 가정). GOVERNANCE 모드에 있는 개체의 경우, 권한을 bypass-governance-retention 부여받은 사용자는 보존 기간 만료일 이전에 개체 버전을 삭제할 수 있습니다.

새 오브젝트의 보존 기간은 버킷에 설정된 기본값에서 상속되거나 보존 종료 날짜를 지정하여 오브젝트를 작성할 때 명시적으로 정의될 수 있습니다.

버킷 기본 설정을 사용할 때 보유 종료 날짜를 지정하지 않습니다. 대신 버킷에 배치된 모든 오브젝트 버전을 보호해야 하는 기간 (일 또는 년) 을 지정합니다. 버킷에 오브젝트를 배치하면 오브젝트 쓰기 시간에 지정된 지속 기간을 추가하여 오브젝트 버전에 대한 보유 종료 날짜가 계산됩니다.

버킷에 오브젝트 버전을 배치하기 위한 요청에 명시적 보존 모드 및 유지 종료 날짜가 포함된 경우 해당 설정은 해당 오브젝트 버전에 대한 버킷 기본 설정을 대체합니다.

다른 모든 오브젝트 잠금 설정과 마찬가지로, 보유 종료 날짜는 개별 오브젝트 버전에 적용됩니다. 단일 오브젝트의 다른 버전에는 다른 보존 모드 및 기간이 있을 수 있습니다.

90일보존 기간으로 60일이 소요되는 오브젝트를 가정하고 동일한 이름과 2년 보존 기간으로 해당 오브젝트를 겹쳐씁니다. 조작이 성공하고 보존 기간이 2년인 오브젝트의 새 버전이 작성됩니다. 한편, 30일이 더 지나면 원래 버전을 삭제할 수 있습니다.

보존 기간 연장

오브젝트의 보존 기간을 연장하려면 새 더 긴 보존 기간을 설정하는 요청을 전송하기만 하면 됩니다. 요청자에게 cloud-object-storage.object.put_object_lock_retentioncloud-object-storage.object.put_object_lock_retention_version 조치가 있다고 가정하여 이전 값을 새 값으로 겹쳐씁니다.

보관 기간 단축

GOVERNANCE 모드로 보호되는 객체의 경우, 권한이 부여된 사용자는 요청에 x-amz-bypass-governance-retention 헤더를 포함하고 적절한 권한(cloud-object-storage.object.bypass_governance_retention, cloud-object-storage.object.put_object_lock_retentioncloud-object-storage.object.put_object_lock_retention_version)을 보유한 경우 보존 기간을 더 이른 날짜로 단축할 수 있습니다.

컴플라이언스 모드에 있는 개체는 보존 기간 만료일 이전에 보존 기간을 단축하거나 제거할 수 없습니다.

Object Lock 시작하기

시작하기 위해 몇 가지 전제조건이 있습니다.

  • 버킷에서 Writer 또는 Manager 플랫폼 역할이 필요하거나 적절한 조치 (예: cloud-object-storage.bucket.put_object_lock_configuration) 가 지정된 사용자 정의 역할이 필요합니다.
  • 오브젝트 버전화가 사용 가능해야 합니다.
  • 표준 가격 책정 플랜을 사용해야 합니다. 세부사항은 가격 책정 을 참조하십시오.
  • 오브젝트 잠금이 지원되는 지역을 선택해야 합니다. 자세한 내용은 통합 서비스 를 참조하십시오.
  • 최대 기본 보존 기간인 100년 (또는 36500일) 이 지원됩니다.
  • 콘솔을 사용할 때 일 또는 년 외에 월 단위로 보유 종료 날짜를 설정할 수도 있습니다.

컴플라이언스 모드에서는 객체의 보존 기간을 줄일 수 없습니다. 거버넌스 모드에서는 ' BypassGovernanceRetention ' 권한을 가진 승인된 사용자가 필요 시 보존 기간을 단축하거나 제거할 수 있습니다. 검증 테스트를 위해 더 짧은 기본 보존 기간(예: 1일)을 사용하고 필요에 따라 조정하는 것이 권장됩니다.

오브젝트 잠금에 사용할 새 버킷 작성 및 설정

  1. 원하는 Object Storage 인스턴스를 탐색하고 버킷 사용자 정의 옵션 과 함께 버킷 작성 을 사용하십시오.
  2. 유스 케이스 요구사항에 따라 필수 버킷 구성 세부사항을 입력하십시오.
  3. 오브젝트 버전화 섹션으로 이동하여 사용 으로 설정하십시오.
  4. 불변성을 찾고 오브젝트 잠금 아래에서 추가 를 클릭하십시오.
  5. 오브젝트 잠금을 사용 으로 설정하십시오.
  6. 선택적으로 기본 보존 기간을 설정하십시오.
  7. 저장을 클릭하십시오.
  8. 나머지 구성 설정을 진행하고 버킷 작성 을 클릭하십시오.

기존 버킷에서 오브젝트 잠금 사용:

다음과 같이 오브젝트 잠금 사용에 대해 버킷을 설정할 수 있습니다.

  1. 버킷 구성 섹션으로 이동하십시오.
  2. 오브젝트 버전화 를 클릭하십시오.
  3. 오브젝트 버전화 섹션에서 편집을 클릭하고 구성 옵션을 사용 으로 설정한 후 저장 하십시오.
  4. 오브젝트 잠금 섹션으로 이동하여 추가 를 클릭하십시오.
  5. 오브젝트 잠금사용 가능 으로 설정하십시오.
  6. 선택적으로 기본 보존 기간을 설정하십시오.
  7. ‘저장 ’을 클릭하세요

오브젝트에 보유 종료 날짜 또는 법적 보류 추가

  1. 대상 오브젝트가 있는 버킷으로 이동하십시오.
  2. 버전 표시 토글
  3. 대상 버전의 세부사항으로 이동
  4. 보존 기간을 추가하거나 법적 보존을 전환하십시오.

비즈니스 연속성 및 재해 복구를 위해 Object Lock 사용

오브젝트 잠금을 사용하면 보호된 데이터를 수정하거나 영구 삭제할 수 없으므로 랜섬웨어 공격 시 서비스 연속성을 제공할 수 있습니다.

일관성 및 데이터 무결성

IBM Cloud Object Storage 은 모든 데이터 IO 작업에 대해 강력한 일관성을 제공하지만, 버킷 구성은 결국 일관성을 유지합니다. 버킷에서 기본 보존 기간을 사용으로 설정, 수정 또는 삭제한 후 구성이 시스템 전체에 전파되는 데 몇 분이 걸릴 수 있습니다. 오브젝트에 대한 조작 (예: 증거보존 통지 추가) 은 즉시 일치합니다.

사용량 및 계정

잠긴 오브젝트 (및 해당 버전) 는 다른 데이터와 마찬가지로 사용에 기여하며 오브젝트가 보존 기간 동안 잠겨 있는 동안에는 사용 비용 에 대한 책임이 사용자에게 있습니다.

상호작용

오브젝트 잠금은 유스 케이스 요구사항에 따라 여러 오브젝트 스토리지 기능과 함께 사용할 수 있습니다.

버전화

버전화 사용 은 오브젝트 잠금을 사용하기 위한 전제조건입니다. x-amz-bucket-object-lock-enabled 헤더를 사용하여 버킷을 작성하면 버전화가 자동으로 사용으로 설정됩니다.

버전화된 오브젝트를 삭제하면 _삭제 마커_가 작성됩니다. 해당 개체가 삭제된 것처럼 보일 수 있으나, 개체가 보호된 상태라면 COMPLIANCE 모드에서 보호된 버전을 삭제하는 것은 불가능합니다. 삭제 마커 자체는 보호되지 않습니다. 그러나 거버넌스 모드로 잠긴 개체의 경우, 해당 개체에 법적 보존 요청이 활성화되어 있지 않은 한, 권한을 bypass-governance-retention 부여받은 사용자는 보존 기간이 만료되기 전에 해당 개체를 삭제할 수 있습니다.

복제

Object Lock은 복제와 함께 사용할 수 있습니다. 복제 소스 버킷과 대상 버킷 모두에서 오브젝트 잠금(Object Lock)이 활성화된 경우, 소스 오브젝트 버전에 적용된 모든 오브젝트 잠금 상태가 대상 버킷으로 복제됩니다. 여기에는 거버넌스 우회와 관련된 모든 Object Lock 업데이트가 포함됩니다. 자세한 내용은 ‘객체 복제’를 참조하십시오.

키 관리 시스템

보호 오브젝트는 버킷의 루트 키를 사용하여 암호화됩니다. 버킷에서 오브젝트 잠금을 사용하는 경우 Key Protect 또는 Hyper Protect Crypto Services 에서 호스팅하는 루트 키는 연관된 버킷에서 오브젝트 잠금을 사용하는 한 삭제되지 않도록 보호됩니다. 이는 보호 오브젝트의 암호화 폐기를 방지합니다.

라이프사이클 구성

잠긴 오브젝트를 아카이브하는 라이프사이클 정책을 사용으로 설정할 수 있지만 보존 또는 증거보존 중인 오브젝트를 만료 하는 정책은 사용으로 설정할 수 없습니다 (버킷의 비보호 오브젝트는 여전히 만료될 수 있음).

불변 오브젝트 스토리지

오브젝트 잠금은 불변 Object Storage를 사용할 때 사용 가능한 보존 정책의 대안입니다. 오브젝트 잠금을 사용하려면 버전화를 사용해야 하고 불변 Object Storage 는 버전화와 호환되지 않으므로 동일한 버킷에서 두 WORM 솔루션을 모두 사용할 수 없습니다. 서비스 인스턴스에서 각각 불변 Object Storage 또는 오브젝트 잠금을 사용하는 버킷을 혼합하여 사용할 수 있습니다.

오브젝트 태그 지정

보호 오브젝트에서 태그를 추가하거나 수정하는 것에 대한 제한사항은 없습니다.

기타 상호작용

CORS 정책 설정, IP 방화벽 또는 조건 기반 제한 설정, 버킷 할당량 설정, Code Engine 등 다른 Object Storage 기능과 Object Lock을 함께 사용할 때 부정적인 상호 작용이 없어야 합니다.

IAM 조치

오브젝트 잠금과 연관된 새 IAM 조치가 있습니다.

IAM 조치
IAM 조치 역할
cloud-object-storage.bucket.get_object_lock_configuration 관리자, 작성자, 독자
cloud-object-storage.bucket.put_object_lock_configuration 관리자, 작성자
cloud-object-storage.object.get_object_lock_retention 관리자, 작성자, 독자
cloud-object-storage.object.put_object_lock_retention 관리자, 작성자
cloud-object-storage.object.get_object_lock_retention_version 관리자, 작성자, 독자
cloud-object-storage.object.put_object_lock_retention_version 관리자, 작성자
cloud-object-storage.object.get_object_lock_legal_hold 관리자, 작성자, 독자
cloud-object-storage.object.put_object_lock_legal_hold 관리자, 작성자
cloud-object-storage.object.get_object_lock_legal_hold_version 관리자, 작성자, 독자
cloud-object-storage.object.put_object_lock_legal_hold_version 관리자, 작성자
cloud-object-storage.object.bypass_governance_retention 관리자, 작성자

작성자 역할이 있는 사용자는 수년 (아마도 천년) 동안 오브젝트를 삭제 불가능하게 만들 수 있습니다. 주의하고 대부분의 사용자가 보유 종료 날짜를 설정하도록 허용하지 않는 사용자 정의 역할을 작성하는 것을 고려하십시오.

Activity Tracker 이벤트

오브젝트 잠금은 추가 이벤트를 생성합니다.

  • cloud-object-storage.bucket-object-lock.create
  • cloud-object-storage.bucket-object-lock.read
  • cloud-object-storage.object-object-lock-legal-hold.create
  • cloud-object-storage.object-object-lock-legal-hold.read
  • cloud-object-storage.object-object-lock-retention.create
  • cloud-object-storage.object-object-lock-retention.read

cloud-object-storage.bucket-object-lock.create 이벤트의 경우 다음 필드는 추가 정보를 제공합니다.

필드 설명
requestData.object_lock_configuration.enabled 버킷에서 오브젝트 잠금이 사용으로 설정되었음을 표시합니다.
requestData.object_lock_configuration.defaultRetention.mode 또는 GOVERNANCE 모드가 COMPLIANCE 활성화되었음을 나타냅니다.
object_lock_configuration.defaultRetention.years 기본 보존 기간 (년) 입니다.
object_lock_configuration.defaultRetention.days 기본 보존 기간 (일) 입니다.

object_lock_configuration.defaultRetention.years 또는 object_lock_configuration.defaultRetention.days 만 존재하지만 동시에 둘 다 존재하지는 않습니다.

보호 오브젝트에 대한 조작의 경우 다음 필드가 있을 수 있습니다.

필드 설명
requestData.object_lock_protection.legal_hold 오브젝트 버전에서 증거보존 통지가 적용되고 있음을 표시합니다.
requestData.object_lock_protection.retention.mode 객체 버전에 대해 표시하거나 GOVERNANCE 모드가 COMPLIANCE 활성화됨을 나타냅니다.
requestData.object_lock_protection.retention.retain_until_date 오브젝트 버전을 삭제할 수 있는 날짜를 표시합니다. 이 날짜 이후에는 오브젝트가 보존 날짜를 기반으로 더 이상 보호되어 삭제되지 않습니다.

REST API 예제

다음 예제는 사용하기 쉽도록 cURL 을 사용하여 표시됩니다. 환경 변수는 $BUCKET, $TOKEN$REGION 와 같은 사용자 특정 요소를 표시하는 데 사용됩니다. $REGION 에는 모든 네트워크 유형 스펙도 포함되므로 사설 네트워크를 사용하여 us-south 의 버킷에 요청을 전송하려면 변수를 private.us-south 로 설정해야 합니다.

버킷에서 오브젝트 잠금 사용

오브젝트 잠금 구성은 요청 본문에서 XML로 제공됩니다. 새 요청은 버킷에 있는 기존 복제 규칙을 겹쳐씁니다.

오브젝트 잠금 구성은 하나의 규칙을 포함해야 합니다.

선택적 헤더
헤더 유형 설명
Content-MD5 문자열 base64 는 페이로드의 128비트 MD5 해시 값을 인코딩했으며, 이는 전송 중에 페이로드가 변조되지 않았는지 확인하기 위한 무결성 검사 목적으로 사용됩니다.
x-amz-checksum-crc32 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32 체크섬입니다.
x-amz-checksum-crc32c 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32C 체크섬입니다.
x-amz-checksum-crc64nvme 문자열 이 헤더는 개체의 Base64 인코딩된 64비트 CRC64NVME 체크섬입니다. CRC64NVME 체크섬은 항상 전체 객체 체크섬입니다.
x-amz-checksum-sha1 문자열 이 헤더는 개체의 Base64 인코딩된 160비트 SHA1 다이제스트입니다.
x-amz-checksum-sha256 문자열 이 헤더는 개체의 Base64 인코딩된 256비트 SHA256 다이제스트입니다.
x-amz-sdk-checksum-algorithm 문자열 SDK를 사용할 때 오브젝트의 체크섬을 생성하는 데 사용되는 알고리즘을 나타냅니다.
x-amz-bypass-governance-retention 문자열 이 헤더를 통해 권한이 부여된 사용자는 GOVERNANCE 모드 보존 설정을 무시하고, 보존 기간 만료일 이전에 개체를 삭제하거나 수정할 수 있습니다.

페이로드에 대한 무결성 검사로 Content-MD5 헤더 또는 checksum 헤더( x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1, x-amz-checksum-sha256 포함)가 필요합니다.

요청 본문에 다음 스키마가 포함된 XML 블록이 있어야 합니다.

요소 유형 하위 상위 제한조건
ObjectLockConfiguration 컨테이너 ObjectLockEnabled, Rule 없음 필수 한계 1.
ObjectLockEnabled 문자열 없음 ObjectLockConfiguration 필수 유일하게 올바른 값은 Enabled (대소문자 구분) 입니다.
Rule 컨테이너 DefaultRetention ObjectLockConfiguration 한계 1
DefaultRetention 컨테이너 Days, Mode, Years Rule 한계 1.
Days 정수 없음 DefaultRetention 기본 보존 기간에 대해 지정할 일 수입니다. Years 와 결합할 수 없습니다.
Mode 문자열 없음 DefaultRetention COMPLIANCE 또는 GOVERNANCE (대소문자 구분).
Years 정수 없음 DefaultRetention 기본 보존 기간에 대해 지정할 년 수입니다. Days 와 결합할 수 없습니다.

이 예제에서는 새 오브젝트를 최소 30일동안 보존합니다.

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?object-lock" \
     -H 'Authorization: bearer $TOKEN' \
     -H 'Content-MD5: exuBoz2kFBykNwqu64JZuA==' \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'<ObjectLockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
            <ObjectLockEnabled>Enabled</ObjectLockEnabled>
            <Rule>
                <DefaultRetention>
                  <Days>30</Days>
                  <Mode>COMPLIANCE</Mode>
                </DefaultRetention>
            </Rule>
          </ObjectLockConfiguration>'

성공적인 요청은 200 응답을 리턴합니다.

버킷의 객체 잠금 구성 보기

curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?object-lock" \
     -H 'Authorization: bearer $TOKEN'

이는 적절한 스키마가 있는 XML 응답 본문을 리턴합니다.

<ObjectLockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <ObjectLockEnabled>string</ObjectLockEnabled>
  <Rule>
      <DefaultRetention>
        <Days>30</Days>
        <Mode>COMPLIANCE</Mode>
      </DefaultRetention>
  </Rule>
</ObjectLockConfiguration>

오브젝트에 대한 보존 기간 추가 또는 확장

오브젝트 잠금 구성은 요청 본문에서 XML로 제공됩니다. 새 요청은 해당 객체에 존재하는 기존 복제 규칙을 덮어씁니다. 단, RetainUntilDate 요청된 복제 시점이 현재 값보다 먼 미래여야 하며, 객체가 GOVERNANCE 모드에서 잠겨 있고 요청자가 해당 bypass-governance-retention 권한을 보유한 경우에 한합니다.

선택적 헤더
헤더 유형 설명
Content-MD5 문자열 base64 는 페이로드의 128비트 MD5 해시 값을 인코딩했으며, 이는 전송 중에 페이로드가 변조되지 않았는지 확인하기 위한 무결성 검사 목적으로 사용됩니다.
x-amz-checksum-crc32 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32 체크섬입니다.
x-amz-checksum-crc32c 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32C 체크섬입니다.
x-amz-checksum-crc64nvme 문자열 이 헤더는 개체의 Base64 인코딩된 64비트 CRC64NVME 체크섬입니다. CRC64NVME 체크섬은 항상 전체 객체 체크섬입니다.
x-amz-checksum-sha1 문자열 이 헤더는 개체의 Base64 인코딩된 160비트 SHA1 다이제스트입니다.
x-amz-checksum-sha256 문자열 이 헤더는 개체의 Base64 인코딩된 256비트 SHA256 다이제스트입니다.
x-amz-sdk-checksum-algorithm 문자열 SDK를 사용할 때 오브젝트의 체크섬을 생성하는 데 사용되는 알고리즘을 나타냅니다.
x-amz-bypass-governance-retention 문자열 이 헤더를 통해 권한이 부여된 사용자는 GOVERNANCE 모드 보존 설정을 무시하고, 보존 기간 만료일 이전에 개체를 삭제하거나 수정할 수 있습니다.

페이로드에 대한 무결성 검사로 Content-MD5 헤더 또는 checksum 헤더( x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1, x-amz-checksum-sha256 포함)가 필요합니다.

선택적으로 RetainUntilDate 를 적용할 버전을 지정할 수 있습니다.

선택적 조회 매개변수

매개변수 필수? 유형 설명
versionID 선택사항 문자열 버전 ID입니다.

요청 본문에 다음 스키마가 포함된 XML 블록이 있어야 합니다.

요소 유형 하위 상위 제한조건
Retention 컨테이너 Mode, RetainUntilDate 없음 필수 한계 1.
Mode 문자열 없음 Retention **필수 **COMPLIANCE 또는 GOVERNANCE (대소문자 구분).
RetainUntilDate 문자열 없음 Retention 필수 오브젝트가 삭제에 적합한 날짜입니다 ( ISO8601 날짜-시간 형식).

이 예는 적어도 2023년 3월 12일까지 새 오브젝트를 보유합니다.

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?retention" \
     -H 'Authorization: Bearer $TOKEN' \
     -H 'Content-MD5: fT0hYstki6zUvEh7abhcTA==' \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'<Retention>
            <Mode>COMPLIANCE</Mode>
            <RetainUntilDate>2023-03-12T23:01:00.000Z</RetainUntilDate>
          </Retention>'

성공적인 요청은 200 응답을 리턴합니다.

RetainUntilDate 값이 기존 값을 초과하지 않는 경우 조작은 403 Access Denied 로 실패합니다.

이 예시는 GOVERNANCE 모드 하에서 보호되는 기존 객체 버전의 보존 기간을 단축합니다. 요청자는 거버넌스 우회 및 보존 권한을 보유해야 합니다.

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/$OBJECT?retention" \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-MD5: fT0hYstki6zUvEh7abhcTA==" \
     -H "Content-Type: text/plain; charset=utf-8" \
     -H "x-amz-bypass-governance-retention: true" \
     -d $'<Retention>
            <Mode>GOVERNANCE</Mode>
            <RetainUntilDate>2023-02-10T23:01:00.000Z</RetainUntilDate>
          </Retention>'

성공적인 요청은 200 OK 응답을 반환합니다. 요청자가 권한이 bypass-governance-retention 없거나 헤더가 생략된 경우, 작업은 403 Access Denied 오류로 실패합니다.

오브젝트에 대한 증거보존 통지 추가 또는 제거

오브젝트 잠금 구성은 요청 본문에서 XML로 제공됩니다. RetainUntilDate 가 현재 값보다 나중인 경우 새 요청은 오브젝트에 있는 기존 복제 규칙을 겹쳐씁니다.

선택적 헤더
헤더 유형 설명
Content-MD5 문자열 base64 는 페이로드의 128비트 MD5 해시 값을 인코딩했으며, 이는 전송 중에 페이로드가 변조되지 않았는지 확인하기 위한 무결성 검사 목적으로 사용됩니다.
x-amz-checksum-crc32 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32 체크섬입니다.
x-amz-checksum-crc32c 문자열 이 헤더는 개체의 Base64 인코딩된 32비트 CRC32C 체크섬입니다.
x-amz-checksum-crc64nvme 문자열 이 헤더는 개체의 Base64 인코딩된 64비트 CRC64NVME 체크섬입니다. CRC64NVME 체크섬은 항상 전체 객체 체크섬입니다.
x-amz-checksum-sha1 문자열 이 헤더는 개체의 Base64 인코딩된 160비트 SHA1 다이제스트입니다.
x-amz-checksum-sha256 문자열 이 헤더는 개체의 Base64 인코딩된 256비트 SHA256 다이제스트입니다.
x-amz-sdk-checksum-algorithm 문자열 SDK를 사용할 때 오브젝트의 체크섬을 생성하는 데 사용되는 알고리즘을 나타냅니다.

페이로드에 대한 무결성 검사로 Content-MD5 헤더 또는 checksum 헤더( x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1, x-amz-checksum-sha256 포함)가 필요합니다.

요청 본문에 다음 스키마가 포함된 XML 블록이 있어야 합니다.

요소 유형 하위 상위 제한조건
legal-hold 컨테이너 Status 없음 한계 1.
Status 문자열 없음 legal-hold 지원되는 값은 ON 또는 OFF (대소문자 구분) 입니다.

이 예는 적어도 2023년 3월 12일까지 새 오브젝트를 보유합니다.

curl -X "PUT" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?legal-hold&versionId=$VERSION_ID" \
     -H 'Authorization: Bearer $TOKEN' \
     -H 'Content-MD5: FMh6GxizXUBRaiDuB0vtgQ==' \
     -H 'Content-Type: text/plain; charset=utf-8' \
     -d $'<legal-hold>
            <Status>ON</Status>
          </legal-hold>'

성공적인 요청은 200 응답을 리턴합니다.

SDK 예제

다음 예시는 Python, Node.js, Java 및 Go용 IBM COS SDK와 Terraform 스크립트를 활용합니다. 다만 객체 버전 관리 구현은 사용자 지정 엔드포인트 설정이 가능한 모든 S3-compatible 라이브러리 또는 도구와 완전히 호환되어야 합니다. 타사 도구를 사용하려면 HMAC 자격 증명을 사용하여 AWS V4 서명을 계산해야 합니다.

Python

Python 용 IBM COS SDK를 사용하여 오브젝트 잠금을 사용으로 설정하는 작업은 하위 레벨 클라이언트 구문을 사용하여 수행할 수 있습니다.

클라이언트 사용:

import ibm_boto3
from ibm_botocore.client import Config
from ibm_botocore.exceptions import ClientError
from datetime import datetime, timedelta
import time

# Create new bucket with Object Lock enabled.
def create_bucket_with_objectlock(bucket_name):
        cos_cli.create_bucket(
            Bucket=bucket_name,
            ObjectLockEnabledForBucket=True,
        )
        print("Bucket: {0} created with objectlock enabled".format(bucket_name))

def objectlock_configuration_on_bucket(bucket_name):

    # Putting default retenion on the COS bucket.
    default_retention_rule = {'DefaultRetention': {'Mode': 'COMPLIANCE', 'Years': 1}}
    object_lock_config = {'ObjectLockEnabled': 'Enabled', 'Rule': default_retention_rule}
    cos_cli.put_object_lock_configuration(Bucket=bucket_name, ObjectLockConfiguration=object_lock_config)
    # Reading the objectlock configuration set on the bucket.
    response = cos_cli.get_object_lock_configuration(Bucket=bucket_name)
    print("Objectlock Configuration for {0} =>".format(bucket_name))
    print(response.ObjectLockConfiguration)

def objectlock_configuration_with_governance_mode_on_bucket(bucket_name):

    # Putting default retenion on the COS bucket with governance mode.
    default_retention_rule = {'DefaultRetention': {'Mode': 'GOVERNANCE', 'Years': 1}}
    object_lock_config = {'ObjectLockEnabled': 'Enabled', 'Rule': default_retention_rule}
    cos_cli.put_object_lock_configuration(Bucket=bucket_name, ObjectLockConfiguration=object_lock_config)
    # Reading the objectlock configuration set on the bucket.
    response = cos_cli.get_object_lock_configuration(Bucket=bucket_name)
    print("Objectlock Configuration for {0} =>".format(bucket_name))
    print(response.ObjectLockConfiguration)

def upload_object(bucket_name,object_name,object_content):
        cos_cli.put_object(
            Bucket=bucket_name,
            Key=object_name,
            Body=object_content
        )
        print("Object: {0} uploaded!".format(object_name))

def upload_object_with_governance_mode(bucket_name,object_name,object_content):
        cos_cli.put_object(
            Bucket=bucket_name,
            Key=object_name,
            Body=object_content,
            ObjectLockMode='GOVERNANCE',
            ObjectLockRetainUntilDate=datetime(2025, 11, 15)
        )
        print("Object: {0} uploaded!".format(object_name))

def objectlock_retention(bucket_name,object_name):
        # Put objectlock retenion on the  object uploaded to the bucket.
        date = datetime.now()+timedelta(seconds=5)
        retention_rule = {'Mode': 'COMPLIANCE', 'RetainUntilDate': date}
        cos_cli.put_object_retention(Bucket=bucket_name, Key=object_name, Retention=retention_rule)

        # Get objectlock retention of the above object.
        response = cos_cli.get_object_retention(Bucket=bucket_name, Key=object_name)
        print("Objectlock Retention for {0}=>".format(object_name))
        print(response.Retention)

def objectlock_retention_with_governance_mode(bucket_name,object_name):
        # Put objectlock retenion with governance mode on the  object uploaded to the bucket.
        date = datetime.now()+timedelta(seconds=5)
        retention_rule = {'Mode': 'GOVERNANCE', 'RetainUntilDate': date}
        cos_cli.put_object_retention(Bucket=bucket_name, Key=object_name, Retention=retention_rule)

        # Get objectlock retention of the above object.
        response = cos_cli.get_object_retention(Bucket=bucket_name, Key=object_name)
        print("Objectlock Retention for {0}=>".format(object_name))
        print(response.Retention)

def objectlock_legal_hold(bucket_name,object_name):
        # Setting the objectlock legal-hold status to ON.
        cos_cli.put_object_legal_hold(Bucket=bucket_name, Key=object_name, legal_hold={'Status': 'ON'})
        # Get objectlock retention of the above object.
        response = cos_cli.get_object_legal_hold(Bucket=bucket_name, Key=object_name)
        print("Objectlock legal-hold for {0}=>".format(object_name))
        print(response.legal_hold)

def delete_object_with_bypass_governance(bucket_name,object_name):
        # Deleting an object with retention using bypass governance
        cos_cli.delete_object(Bucket=bucket_name, Key=object_name, BypassGovernanceRetention=True)

COS_ENDPOINT = "" #Current list avaiable at https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints -> Ex:https://s3.us-south.cloud-object-storage.appdomain.cloud
COS_API_KEY_ID = "" #API Key of the cos instance created Ex: W00YixxxxxxxxxxMB-odB-2ySfTrFBIQQWanc--P3byk
COS_RESOURCE_INSTANCE_CRN = "" #API key of cos instance example: xxxd12V2QHXbjaM99G9tWyYDgF_0gYdlQ8aWALIQxXx4

# Create client connection
cos_cli = ibm_boto3.client("s3",
    ibm_api_key_id=COS_API_KEY_ID,
    config=Config(signature_version="oauth"),
    endpoint_url=COS_ENDPOINT,
    ibm_service_instance_id=COS_RESOURCE_INSTANCE_CRN,
    ibm_auth_endpoint="https://iam.cloud.ibm.com/identity/token"
)
new_bucket_name = "create-example-python12345" # bucket name should be unique gloablly, or else it will throw an error.
new_text_file_name = "cos_object.txt"
new_text_file_contents = "This is a test file from Python code sample!!!"

# *** Main Program ***
def main():
       create_bucket_with_objectlock(new_bucket_name) # Create a new cos bucket with object lock enabled.
       objectlock_configuration_on_bucket(new_bucket_name) # Put objectlock configuration(i.e. default retention) on COS bucket and get the configuration.
       objectlock_configuration_with_governance_mode_on_bucket(new_bucket_name) # Put objectlock configuration(i.e. default retention)with governance mode on COS bucket and get the configuration.
       upload_object(new_bucket_name,new_text_file_name,new_text_file_contents) # Upload an object to cos bucket.
       upload_object_with_governance_mode(new_bucket_name,new_text_file_name,new_text_file_contents) # Upload an object to cos bucket with governance mode.
       objectlock_retention(new_bucket_name,new_text_file_name) # Put objectlock retention(i.e. retain until date) on the object and get the configured retention.
       objectlock_retention_with_governance_mode(new_bucket_name,new_text_file_name) # Put objectlock retention(i.e. retain until date) with governance mode on the object and get the configured retention.
       objectlock_legal_hold(new_bucket_name,new_text_file_name)  # Put objectlock legal-hold on the object and get the legal-hold status.
       delete_object_with_bypass_governance(new_bucket_name,new_text_file_name) # Deleting an object with retention with governance mode using bypass governance.
if __name__ == "__main__":
    main()

Node.js

IBM COS SDK for Node.js 를 사용하여 버전화 사용:

'use strict';

// Required libraries
const ibm = require('ibm-cos-sdk');
const fs = require('fs');
const crypto = require('crypto');

function logError(e) {
    console.log(`ERROR: ${e.code} - ${e.message}\n`);
}

function logDone() {
    console.log('DONE!\n');
}

const COS_ENDPOINT = "";   //Choose endpoint from https://control.cloud-object-storage.cloud.ibm.com/v2/endpoints. Ex: https://s3.us-south.cloud-object-storage.appdomain.cloud
const COS_API_KEY_ID = "";  // API key of cos instance example: xxxd12V2QHXbjaM99G9tWyYDgF_0gYdlQ8aWALIQxXx4
const COS_AUTH_ENDPOINT = "";
const COS_RESOURCE_INSTANCE_CRN = ""; // example: crn:v1:bluemix:public:cloud-object-storage:global:a <CREDENTIAL_ID_AS_GENERATED>:<SERVICE_ID_AS_GENERATED>::

// Client Creation.
var config = {
    endpoint: COS_ENDPOINT,
    apiKeyId: COS_API_KEY_ID,
    ibmAuthEndpoint: COS_AUTH_ENDPOINT,
    serviceInstanceId: COS_RESOURCE_INSTANCE_CRN,
    signatureVersion: 'iam'
};

var cos = new ibm.S3(config);

// Create new bucket with objectlock enabled.
function createBucket(bucketName) {
    console.log(`Creating new bucket: ${bucketName}`);
    return cos.createBucket({
        Bucket: bucketName,
        ObjectLockEnabledForBucket: true,
        CreateBucketConfiguration: {
            LocationConstraint: ''
          },
    }).promise()
    .then((() => {
        console.log(`Bucket: ${bucketName} created!`);
    }))
    .catch((e) => {
        console.error(`ERROR: ${e.code} - ${e.message}\n`);
    });
}

// Create new text file and upload the object to COS bucket.
function createTextFile(bucketName, itemName, fileText) {
    console.log(`Creating new item: ${itemName}`);
    return cos.putObject({
        Bucket: bucketName,
        Key: itemName,
        Body: fileText
    }).promise()
    .then(() => {
        console.log(`Item: ${itemName} created!`);
        logDone();
    })
    .catch(logError);
}

function uploadFileWithGovernanceMode(bucketName, itemName, fileText) {
    var inFiveSecond = (new Date(Date.now() + (1000 * 5)))
    console.log(`Creating new item: ${itemName}`);
    return cos.putObject({
        Bucket: bucketName,
        Key: itemName,
        Body: fileText,
        ObjectLockMode: "GOVERNANCE",
        ObjectLockRetainUntilDate: inFiveSecond,

    }).promise()
    .then(() => {
        console.log(`Item: ${itemName} created!`);
        logDone();
    })
    .catch(logError);
}

function putObjectLockConfigurationOnBucket(bucketName) {
    console.log(`Putting Objectlock Configuration on : ${bucketName}`);
    // Putting objectlock configuration
    var defaultRetention = {Mode: 'COMPLIANCE', Days: 1}
    var objectLockRule = {DefaultRetention : defaultRetention}
    var param = {ObjectLockEnabled: 'Enabled', Rule: objectLockRule}
    return cos.putObjectLockConfiguration({
        Bucket: bucketName,
        ObjectLockConfiguration: param
    }).promise()
    .then(() => {
        console.log(`Object lock Configurtion added!!`);
        logDone();
    })
    .catch(logError);
}

function putObjectLockConfigurationWithGovernanceModeOnBucket(bucketName) {
    console.log(`Putting Objectlock Configuration on : ${bucketName}`);
    // Putting objectlock configuration
    var defaultRetention = {Mode: 'GOVERNANCE', Days: 1}
    var objectLockRule = {DefaultRetention : defaultRetention}
    var param = {ObjectLockEnabled: 'Enabled', Rule: objectLockRule}
    return cos.putObjectLockConfiguration({
        Bucket: bucketName,
        ObjectLockConfiguration: param
    }).promise()
    .then(() => {
        console.log(`Object lock Configurtion with Governance mode added!!`);
        logDone();
    })
    .catch(logError);
}

function getObjectLockConfigurationonBucket(bucketName) {
    console.log(`Getting Objectlock Configuration for : ${bucketName}`);
    // Getting objectlock configuration
    return cos.getObjectLockConfiguration({
        Bucket: bucketName,
    }).promise()
    .then((data) => {
        console.log(`objectlock configuration`);
        console.log( JSON.stringify(data.ObjectLockConfiguration, null, "    ") );
        logDone();
    })
    .catch(logError);
}

function putObjectLockRetention(bucketName,keyName) {
    console.log(`Putting Objectlock Retention on : ${keyName}`);
    var inFiveSecond = (new Date(Date.now() + (1000 * 5)))
    var rule = {Mode: 'COMPLIANCE', RetainUntilDate: inFiveSecond}
     // Putting objectlock retention
    return cos.putObjectRetention({
        Bucket: bucketName,
        Key: keyName,
        Retention: rule
    }).promise()
    .then(() => {
        console.log(`Object lock Retention added!!`);
        logDone();
    })
    .catch(logError);
}

function putObjectLockRetentionWithGovernanceMode(bucketName,keyName) {
    console.log(`Putting Objectlock Retention on : ${keyName}`);
    var inFiveSecond = (new Date(Date.now() + (1000 * 5)))
    var rule = {Mode: 'GOVERNANCE', RetainUntilDate: inFiveSecond}
     // Putting objectlock retention
    return cos.putObjectRetention({
        Bucket: bucketName,
        Key: keyName,
        Retention: rule
    }).promise()
    .then(() => {
        console.log(`Object lock Retention with governance mode added!!`);
        logDone();
    })
    .catch(logError);
}

function getObjectLockRetention(bucketName,keyName) {
    console.log(`Getting Objectlock Retention for : ${keyName}`);
    // Getting objectlock retention
    return cos.getObjectRetention({
        Bucket: bucketName,
        Key: keyName
    }).promise()
    .then((data) => {
        console.log(`Objectlock retention for : ${keyName} `);
        console.log( JSON.stringify(data.Retention, null, "    ") );
        logDone();
    })
    .catch(logError);
}

function putObjectLocklegalHold(bucketName,keyName) {
    console.log(`Putting Objectlock legal-hold status ON for  : ${keyName}`);
     // Putting objectlock legal-hold status
    return cos.putObjectlegalHold({
        Bucket: bucketName,
        Key: keyName,
        LegalHold: {Status: 'ON'}
    }).promise()
    .then(() => {
        console.log(`Object lock legal-hold added!!`);
        logDone();
    })
    .catch(logError);
}

function getObjectLocklegalHold(bucketName,keyName) {
    console.log(`Getting Objectlock legal-hold for : ${keyName}`);
    // Getting objectlock legal-hold
    return cos.getObjectlegal-hold({
        Bucket: bucketName,
        Key: keyName
    }).promise()
    .then((data) => {
        console.log(`Objectlock legal-hold for : ${keyName} `);
        console.log( JSON.stringify(data.legal-hold, null, "    ") );
        logDone();
    })
    .catch(logError);
}
function createBucket(bucketName,objectName) {
    console.log(`Deleting Object t: ${objectName}`);
    return cos.deleteObject({
  Bucket: bucketName,
  Key: objectName,
  BypassGovernanceRetention: true,
}).promise()
.then(() => {
    console.log("Object deleted");
})
.catch(err => {
    console.error("Error deleting object:", err);
});

}
// Main app
function main() {
    try {
        var newBucketName = "jscosbucket350";
        var newTextFileName = "js_cos_bucket_file.txt";
        var newTextFileContents = "This is a test file from Node.js code sample!!!";

        createBucket(newBucketName) // Create a new cos bucket with object lock enabled.
        .then(() => putObjectLockConfigurationOnBucket(newBucketName)) // Put objectlock configuration(i.e. default retention) on COS bucket.
        .then(() => putObjectLockConfigurationWithGovernanceModeOnBucket(newBucketName)) // Put objectlock configuration(i.e. default retention) with governance mode on COS bucket.
        .then(() => getObjectLockConfigurationonBucket(newBucketName)) // Read objectlock configuration on COS bucket.
        .then(() => createTextFile(newBucketName, newTextFileName, newTextFileContents)) // Upload an object with governance mode to cos bucket.
        .then(() => uploadFileWithGovernanceMode(newBucketName, newTextFileName, newTextFileContents)) // Upload an object to cos bucket.
        .then(() => putObjectLockRetention(newBucketName, newTextFileName)) // Put objectlock retention(i.e. retain until date) on the object.
        .then(() => putObjectLockRetentionWithGovernanceMode(newBucketName, newTextFileName)) // Put objectlock retention(i.e. retain until date) with governance mode on the object.
        .then(() => getObjectLockRetention(newBucketName, newTextFileName)) // Get the configured retention.
        .then(() => putObjectLocklegalHold(newBucketName,newTextFileName)) // Put objectlock legal-hold on the object.
        .then(() => getObjectLocklegalHold(newBucketName,newTextFileName))// Get the legal-hold status.
        .then(() => deleteObjectWithGovernanceMode(newBucketName,newTextFileName)); // Deleting an object with retention using bypass governance
    }
    catch(ex) {
        logError(ex);
    }
}

main();
```### Java
{: #ol-sdks-java}

```java {: codeblock}
mport com.ibm.cloud.objectstorage.ClientConfiguration;
import com.ibm.cloud.objectstorage.SDKGlobalConfiguration;
import com.ibm.cloud.objectstorage.auth.AWSCredentials;
import com.ibm.cloud.objectstorage.auth.AWSStaticCredentialsProvider;
import com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder;
import com.ibm.cloud.objectstorage.oauth.BasicIBMOAuthCredentials;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3ClientBuilder;
import com.ibm.cloud.objectstorage.services.s3.model.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

public class JavaExampleSDK {
    private static AmazonS3 _cosClient;
    private static String api_key;
    private static String service_instance_id;
    private static String endpoint_url;
    private static String location;
    private static String auth_endpoint;

    public static void main(String[] args) throws IOException
    {

        // Constants for IBM COS values
        auth_endpoint = ""; // auth endpoint
        api_key = "";// example: xxxd12V2QHXbjaM99G9tWyYDgF_0gYdlQ8aWALIQxXx4
        service_instance_id = ""; // example: crn:v1:bluemix:public:cloud-object-storage:global:a/xx999cd94a0dda86fd8eff3191349999:9999b05b-x999-4917-xxxx-9d5b326a1111::
        endpoint_url = ""; // example: https://s3.us-south.cloud-object-storage.appdomain.cloud
        location =  "";// example: us-south-standard

        // Create client connection details
        // _cosClient = createClient(api_key, service_instance_id, endpoint_url, location);

        // String bucketName = "java.bucket" + UUID.randomUUID().toString().replace("-","");
        // String itemName = UUID.randomUUID().toString().replace("-","") + "_java_file.txt";
        // String fileText = "This is a test file from the Java code sample!!!";

        // // create a new bucket
        // createBucket(bucketName, _cosClient);

        // // Put objectlock configuration(i.e. default retention) on COS bucket.
        // putObjectLockConfiguration(bucketName , _cosClient);

        // // Put objectlock configuration(i.e. default retention) with governance mode on COS bucket.
        // putObjectLockConfigurationWithGovernanceMode(bucketName , _cosClient);

        // // create a new text file & upload
        // createTextFileAndUpload(bucketName, itemName, fileText);
        // //  Upload an object with governance mode to cos bucket.
        // uploadFileWithGovernanceMode(bucketName, itemName, fileText);

        // //  Put objectlock retention(i.e. retain until date) on the object.
        // putObjectLockRetention(bucketName, itemName, _cosClient);
        // //  Put objectlock retention(i.e. retain until date) with governance mode on the object.
        // putObjectLockRetentionWithGovernanceMode(bucketName, itemName, _cosClient);

        // // remove the object with bypass governance
        // deleteObjectWithBypassGovernance(bucketName);
    }

    // Create client connection
    public static AmazonS3 createClient(String api_key, String service_instance_id, String endpoint_url, String location)
    {
        AWSCredentials credentials;
        credentials = new BasicIBMOAuthCredentials(api_key, service_instance_id);

        ClientConfiguration clientConfig = new ClientConfiguration().withRequestTimeout(5000);
        clientConfig.setUseTcpKeepAlive(true);

        AmazonS3 cosClient = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint_url, location)).withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfig).build();
        return cosClient;
    }

    // Create a new bucket
    public static void createBucket(String bucketName, AmazonS3 _cosClient)
    {
        _cosClient.createBucket(bucketName);
        System.out.printf("Bucket: %s created!\n", bucketName);
    }

    // Put objectlock configuration(i.e. default retention) on COS bucket.
    public static void putObjectLockConfiguration(String bucketName, AmazonS3 _cosClient)
    {
        DefaultRetention defRet = new DefaultRetention()
                .withMode(ObjectLockRetentionMode.COMPLIANCE)
                .withDays(1);
        ObjectLockRule objRule = new ObjectLockRule()
                        .withDefaultRetention(defRet);
        ObjectLockConfiguration objConfig = new ObjectLockConfiguration()
                        .withObjectLockEnabled(ObjectLockEnabled.ENABLED)
                        .withRule(objRule);
        SetObjectLockConfigurationRequest objSet = new SetObjectLockConfigurationRequest()
                        .withBucketName(BUCKET_NAME)
                        .withObjectLockConfiguration(objConfig);
        _cosClient.setObjectLockConfiguration(objSet);
        System.out.printf("Successfully added object lock cofiguration on : %s\n", bucketName);
        GetObjectLockConfigurationRequest objReq = new GetObjectLockConfigurationRequest().withBucketName(BUCKET_NAME);
        GetObjectLockConfigurationResult objRes = _cosClient.getObjectLockConfiguration(objReq);
        ObjectLockConfiguration objLckConfig = objRes.getObjectLockConfiguration();
        ObjectLockRule objGetRule = objLckConfig.getRule();
        System.out.printf("ObjectLock Configuration : %s\n", objGetRule);
    }

    // Put objectlock configuration(i.e. default retention) with governance mode on COS bucket.
    public static void putObjectLockConfigurationWithGovernanceMode(String bucketName, AmazonS3 _cosClient)
    {
        DefaultRetention defRet = new DefaultRetention()
                .withMode(ObjectLockRetentionMode.GOVERNANCE)
                .withDays(1);
        ObjectLockRule objRule = new ObjectLockRule()
                        .withDefaultRetention(defRet);
        ObjectLockConfiguration objConfig = new ObjectLockConfiguration()
                        .withObjectLockEnabled(ObjectLockEnabled.ENABLED)
                        .withRule(objRule);
        SetObjectLockConfigurationRequest objSet = new SetObjectLockConfigurationRequest()
                        .withBucketName(BUCKET_NAME)
                        .withObjectLockConfiguration(objConfig);
        _cosClient.setObjectLockConfiguration(objSet);
        System.out.printf("Successfully added object lock cofiguration on : %s\n", bucketName);
        GetObjectLockConfigurationRequest objReq = new GetObjectLockConfigurationRequest().withBucketName(BUCKET_NAME);
        GetObjectLockConfigurationResult objRes = _cosClient.getObjectLockConfiguration(objReq);
        ObjectLockConfiguration objLckConfig = objRes.getObjectLockConfiguration();
        ObjectLockRule objGetRule = objLckConfig.getRule();
        System.out.printf("ObjectLock Configuration : %s\n", objGetRule);

    }

    // Create file and upload to new bucket
    public static void createTextFileAndUpload(String bucketName, String itemName, String fileText) {
        System.out.printf("Creating new item: %s\n", itemName);

        InputStream newStream = new ByteArrayInputStream(fileText.getBytes(Charset.forName("UTF-8")));
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(fileText.length());
        PutObjectRequest req = new PutObjectRequest(bucketName, itemName, newStream, metadata);
        _cosClient.putObject(req);
        System.out.printf("Item: %s created!\n", itemName);
    }

    //  Upload an object with governance mode to cos bucket.
    public static void uploadFileWithGovernanceMode(String bucketName, String itemName, String fileText) {
        System.out.printf("Creating new item: %s\n", itemName);
        LocalDate date = LocalDate.of(2025, 11, 11);
        InputStream newStream = new ByteArrayInputStream(fileText.getBytes(Charset.forName("UTF-8")));
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(fileText.length());
        PutObjectRequest req = new PutObjectRequest(bucketName, itemName, newStream, metadata)
                            .withObjectLockMode("GOVERNANCE")
                            .withObjectLockRetainUntilDate(date);
        _cosClient.putObject(req);
        System.out.printf("Item: %s created!\n", itemName);
    }

    //  Put objectlock retention(i.e. retain until date) on the object.
    public static void putObjectLockRetention(String bucketName,String itemName, AmazonS3 _cosClient)
    {
        LocalDate date = LocalDate.of(2025, 11, 11);
        ObjectLockRetention objRet = new ObjectLockRetention()
                    .withMode("COMPLIANCE")
                    .withRetainUntilDate(date);
        SetObjectRetentionRequest objSet = new SetObjectRetentionRequest()
                    .withBucketName(BUCKET_NAME)
                    .withitemName(itemName)
                    .withRetention(objRet);
                    .withBypassGovernanceRetention(true);
        _cosClient.setObjectRetention(objSet);
        System.out.printf("Successfully added object retention on : %s\n", itemName);
        GetObjectRetentionRequest objReq = new GetObjectRetentionRequest()
            .withBucketName(BUCKET_NAME)
            .withitemName(itemName);
        GetObjectRetentionResult objRes1 = _cosClient.getObjectRetention(objReq);
        ObjectLockRetention objRet1 = objRes1.getRetention();
        System.out.printf("Retention : %s\n", objRet1);
    }

    //  Put objectlock retention(i.e. retain until date) with governance mode on the object.
    public static void putObjectLockRetentionWithGovernanceMode(String bucketName,String itemName, AmazonS3 _cosClient)
    {
        LocalDate date = LocalDate.of(2025, 11, 11);
        ObjectLockRetention objRet = new ObjectLockRetention()
                    .withMode("GOVERNANCE")
                    .withRetainUntilDate(date);
        SetObjectRetentionRequest objSet = new SetObjectRetentionRequest()
                    .withBucketName(BUCKET_NAME)
                    .withitemName(itemName)
                    .withRetention(objRet);
                    .withBypassGovernanceRetention(true);
        _cosClient.setObjectRetention(objSet);
        System.out.printf("Successfully added object retention on : %s\n", itemName);
        GetObjectRetentionRequest objReq = new GetObjectRetentionRequest()
            .withBucketName(BUCKET_NAME)
            .withitemName(itemName);
        GetObjectRetentionResult objRes1 = _cosClient.getObjectRetention(objReq);
        ObjectLockRetention objRet1 = objRes1.getRetention();
        System.out.printf("Retention : %s\n", objRet1);
    }

    // Delete object
    public static void deleteObjectWithBypassGovernance(String bucketName, String itemName) {
        System.out.printf("Deleting item: %s\n", itemName);
        DeleteObjectRequest deleteRequest = new DeleteObjectRequest(BUCKET_NAME, Key)
            .withBypassGovernanceRetention(true);
        _cosClient.deleteObject(deleteRequest);
        System.out.printf("Item: %s deleted!\n", itemName);
    }

}

Go

package main

import (
    "bytes"
    "fmt"
    "time"

    "github.com/IBM/ibm-cos-sdk-go/aws"
    "github.com/IBM/ibm-cos-sdk-go/aws/credentials/ibmiam"
    "github.com/IBM/ibm-cos-sdk-go/aws/session"
    "github.com/IBM/ibm-cos-sdk-go/service/s3"
)

const (
    apiKey            = "<apiKey>"
    serviceInstanceID = "<serviceInstanceID>"
    authEndpoint      = "https://iam.cloud.ibm.com/identity/token"
    serviceEndpoint   = "https://<endpoint>.appdomain.cloud"
)

// Create new bucket with objectlock enabled.
func createBucket(bucketName string, client *s3.S3) {
    createBucketInput := new(s3.CreateBucketInput)
    createBucketInput.Bucket = aws.String(bucketName)
    createBucketInput.ObjectLockEnabledForBucket = aws.Bool(true)
    _, e := client.CreateBucket(createBucketInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Bucket Created !!! ")
    }
}

func uploadObject(bucketName string, client *s3.S3, fileName string, fileContent string) {
    putInput := &s3.PutObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(fileName),
        Body:   bytes.NewReader([]byte(fileContent)),
    }

    _, e := client.PutObject(putInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Uploaded!!! ")
    }
}

func uploadObjectWithGovernanceMode(bucketName string, client *s3.S3, fileName string, fileContent string) {
    retention_date := time.Now().Local().Add(time.Second * 5)
    putInput := &s3.PutObjectInput{
        Bucket:                    aws.String(bucketName),
        Key:                       aws.String(fileName),
        Body:                      bytes.NewReader([]byte(fileContent)),
        ObjectLockMode:            aws.String("GOVERNANCE"),
        ObjectLockRetainUntilDate: aws.Time(retention_date),
    }

    _, e := client.PutObject(putInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Uploaded!!! ")
    }
}

func objectLockConfiguration(bucketName string, client *s3.S3) {
    // Putting default retenion on the COS bucket.
    putObjectLockConfigurationInput := &s3.PutObjectLockConfigurationInput{
        Bucket: aws.String(bucketName),
        ObjectLockConfiguration: &s3.ObjectLockConfiguration{
            ObjectLockEnabled: aws.String(s3.ObjectLockEnabledEnabled),
            Rule: &s3.ObjectLockRule{
                DefaultRetention: &s3.DefaultRetention{
                    Mode: aws.String("COMPLIANCE"),
                    Days: aws.Int64(1),
                },
            },
        },
    }
    _, e := client.PutObjectLockConfiguration(putObjectLockConfigurationInput)

    // Reading the objectlock configuration set on the bucket.
    getObjectLockConfigurationInput := new(s3.GetObjectLockConfigurationInput)
    getObjectLockConfigurationInput.Bucket = aws.String(bucketName)
    response, e := client.GetObjectLockConfiguration(getObjectLockConfigurationInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Lock Configuration =>", response.ObjectLockConfiguration)
    }
}

func objectLockConfigurationwithGovernanceMode(bucketName string, client *s3.S3) {
    // Putting default retenion on the COS bucket.
    putObjectLockConfigurationInput := &s3.PutObjectLockConfigurationInput{
        Bucket: aws.String(bucketName),
        ObjectLockConfiguration: &s3.ObjectLockConfiguration{
            ObjectLockEnabled: aws.String(s3.ObjectLockEnabledEnabled),
            Rule: &s3.ObjectLockRule{
                DefaultRetention: &s3.DefaultRetention{
                    Mode: aws.String("GOVERNANCE"),
                    Days: aws.Int64(1),
                },
            },
        },
    }
    _, e := client.PutObjectLockConfiguration(putObjectLockConfigurationInput)

    // Reading the objectlock configuration set on the bucket.
    getObjectLockConfigurationInput := new(s3.GetObjectLockConfigurationInput)
    getObjectLockConfigurationInput.Bucket = aws.String(bucketName)
    response, e := client.GetObjectLockConfiguration(getObjectLockConfigurationInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Lock Configuration =>", response.ObjectLockConfiguration)
    }
}
func objectLockRetention(bucketName string, client *s3.S3, keyName string) {

    // Put objectlock retenion on the  object uploaded to the bucket.
    retention_date := time.Now().Local().Add(time.Second * 5)
    putObjectRetentionInput := &s3.PutObjectRetentionInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(keyName),
        Retention: &s3.ObjectLockRetention{
            Mode:            aws.String("COMPLIANCE"),
            RetainUntilDate: aws.Time(retention_date),
        },
    }
    _, e := client.PutObjectRetention(putObjectRetentionInput)

    // Get objectlock retention of the above object.
    getObjectRetentionInput := new(s3.GetObjectRetentionInput)
    getObjectRetentionInput.Bucket = aws.String(bucketName)
    getObjectRetentionInput.Key = aws.String(keyName)
    response, e := client.GetObjectRetention(getObjectRetentionInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Lock Retention =>", response.Retention)
    }
}

func objectLockRetentionWithGovernanceMode(bucketName string, client *s3.S3, keyName string) {

    // Put objectlock retenion on the  object uploaded to the bucket.
    retention_date := time.Now().Local().Add(time.Second * 5)
    putObjectRetentionInput := &s3.PutObjectRetentionInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(keyName),
        Retention: &s3.ObjectLockRetention{
            Mode:            aws.String("GOVERNANCE"),
            RetainUntilDate: aws.Time(retention_date),
        },
    }
    _, e := client.PutObjectRetention(putObjectRetentionInput)

    // Get objectlock retention of the above object.
    getObjectRetentionInput := new(s3.GetObjectRetentionInput)
    getObjectRetentionInput.Bucket = aws.String(bucketName)
    getObjectRetentionInput.Key = aws.String(keyName)
    response, e := client.GetObjectRetention(getObjectRetentionInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Lock Retention =>", response.Retention)
    }
}

func objectLocklegalHold(bucketName string, client *s3.S3, keyName string) {

    // Setting the objectlock legal-hold status to ON.
    putObjectlegalHoldInput := &s3.PutObjectlegalHoldInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(keyName),
        legalHold: &s3.ObjectLocklegalHold{
            Status: aws.String("ON"),
        },
    }
    _, e := client.PutObjectlegalHold(putObjectlegalHoldInput)
    // Get objectlock retention of the above object.
    getObjectlegalHoldInput := new(s3.GetObjectlegalHoldInput)
    getObjectlegalHoldInput.Bucket = aws.String(bucketName)
    getObjectlegalHoldInput.Key = aws.String(keyName)
    response, e := client.GetObjectlegalHold(getObjectlegalHoldInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Lock legal-hold =>", response.legalHold)
    }
}

func deleteObjectWithBypassGovernance(bucketName string, client *s3.S3, fileName string) {
    deleteObjectInput := new(s3.DeleteObjectInput)
    deleteObjectInput.Bucket = aws.String(bucketName)
    deleteObjectInput.Key = aws.String("foo")
    deleteObjectInput.BypassGovernanceRetention = aws.Bool(true)
    _, e := client.DeleteObject(deleteObjectInput)
    if e != nil {
        fmt.Println(e)
    } else {
        fmt.Println("Object Deleted")
    }

}

func main() {

    bucketName := "gocosbucket353"
    textFileName := "go_cos_bucket_file.txt"
    textFileContents := "This is a test file from Node.js code sample!!!"
    conf := aws.NewConfig().
        WithEndpoint(serviceEndpoint).
        WithCredentials(ibmiam.NewStaticCredentials(aws.NewConfig(),
            authEndpoint, apiKey, serviceInstanceID)).
        WithS3ForcePathStyle(true)

    sess := session.Must(session.NewSession())
    client := s3.New(sess, conf)
    createBucket(bucketName, client)                                                   // Create a new cos bucket with object lock enabled.
    objectLockConfiguration(bucketName, client)                                        // Put objectlock configuration(i.e. default retention) on COS bucket and get the configuration.
    objectLockConfigurationwithGovernanceMode(bucketName, client)                      // Put objectlock configuration(i.e. default retention) with governance mode on COS bucket and get the configuration.
    uploadObject(bucketName, client, textFileName, textFileContents)                   // Upload an object to cos bucket.
    uploadObjectWithGovernanceMode(bucketName, client, textFileName, textFileContents) // Upload an object with governance mode to cos bucket.
    objectLockRetention(bucketName, client, textFileName)                              // Put objectlock retention(i.e. retain until date) on the object and get the configured retention.
    objectLockRetentionWithGovernanceMode(bucketName, client, textFileName)            // Put objectlock retention(i.e. retain until date) with governance mode on the object and get the configured retention.
    objectLocklegalHold(bucketName, client, textFileName)                              // Put objectlock legal-hold on the object and get the legal-hold status.
    deleteObjectWithBypassGovernance(bucketName, client, textFileName)                 // Delete object using governace bypass header
}

Terraform

// Create COS instance.
resource "ibm_resource_instance" "cos_instance" {
  name              = "cos-instance"
  resource_group_id = data.ibm_resource_group.cos_group.id
  service           = "cloud-object-storage"
  plan              = "standard"
  location          = "global"
}

// Create a new bucket with objectlock and object versioning enabled.
resource "ibm_cos_bucket" "bucket" {
  bucket_name           = var.bucket_name
  resource_instance_id  = ibm_resource_instance.cos_instance.id
  region_location  = var.regional_loc
  storage_class          = var.standard_storage_class
  object_versioning {
    enable  = true
  }
  object_lock = true
}

// Set object lock configuration on the bucket by providing the crn of the new COS bucket.
resource ibm_cos_bucket_objectlock_configuration "objectlock" {
 bucket_crn      = ibm_cos_bucket.bucket.crn
 bucket_location = var.regional_loc
 object_lock_configuration{
   objectlockenabled = "Enabled"
   objectlockrule{
     defaultretention{
        mode = "COMPLIANCE"
        days = 6
      }
    }
  }
}

// Upload an object to the COS bucket with objectlock retention and objectlock legal-hold.
resource "ibm_cos_bucket_object" "object_object_lock" {
  bucket_crn      = ibm_cos_bucket.bucket.crn
  bucket_location = ibm_cos_bucket.bucket.region_location
  content         = "Hello World 2"
  key             = "plaintext5.txt"
  object_lock_mode              = "COMPLIANCE"
  object_lock_retain_until_date = "2023-02-15T18:00:00Z"
  object_lock_legal_hold_status = "ON"
  force_delete = true
}