Bloqueo de objetos
Object Lock conserva los registros electrónicos y mantiene la integridad de los datos asegurándose de que las versiones de objetos individuales se almacenen en WORM (Write-Once-Read-Many), de forma no borrable y no regrabable. Esta política se aplica hasta una fecha especificada o la eliminación de cualquier retención legal.
¿Por qué utilizar bloqueo de objeto?
Object Lock ayuda a los clientes a controlar los requisitos de conservación y retención de datos aplicando la inmutabilidad de los datos para sus cargas de trabajo de copia de seguridad, recuperación tras desastre y ciberresiliencia.
El bloqueo de objeto garantiza que nadie puede suprimir los datos de y que no hay forma de suspender la retención en un objeto. Lea detenidamente la documentación antes de bloquear objetos con un periodo de retención.
Al utilizar Object Lock, es su responsabilidad garantizar el cumplimiento de cualquier normativa a la que usted (su organización) pueda estar sujeta cuando se trate de la conservación y el almacenamiento de datos para la retención a largo plazo.
Al utilizar Object Lock, usted es responsable de garantizar que su cuenta de IBM Cloud se mantenga en regla según las políticas y directrices de IBM Cloud mientras los datos estén sujetos a un período de retención. Consulte los términos del servicio IBM Cloud para obtener más información.
Terminología
Existen dos formas de utilizar el bloqueo de objetos para proteger los datos: periodos de retención y retenciones legales.
- Un periodo de retención define un periodo de tiempo durante el cual un objeto no se puede modificar o suprimir.
- Una retención legal también impide que se altere un objeto, pero sólo permanece en su lugar hasta que se levante explícitamente.
Es posible hacer uso de cualquier combinación de estos parámetros-una versión de objeto puede tener uno, ambos, o ninguno.
Retener hasta fecha (periodo de retención)
Si necesita proteger una versión de objeto durante un periodo de tiempo fijo, debe especificar una Retener hasta fecha que determine el periodo en el que no se puede modificar. La versión del objeto se puede suprimir después de que
se haya pasado esta fecha (suponiendo que no haya retenciones legales en la versión del objeto). Para los objetos en modo GOVERNANCE, los usuarios autorizados con el bypass-governance-retention permiso pueden eliminar la versión
del objeto antes de la fecha de retención.
El periodo de retención para objetos nuevos se puede heredar del valor predeterminado establecido en el grupo, o se puede definir explícitamente al escribir el objeto especificando una Retener hasta fecha.
Cuando se utilizan valores predeterminados de grupo, no se especifica una fecha de retención hasta. En su lugar, especifique una duración, en días o años, para la que se debe proteger cada versión de objeto colocada en el grupo. Cuando coloca un objeto en el grupo, se calcula una fecha de retención hasta para la versión del objeto añadiendo la duración especificada a la hora de grabación del objeto.
Si la solicitud para colocar una versión de objeto en un grupo contiene una modalidad de retención explícita y Retener hasta fecha, estos valores alteran temporalmente los valores predeterminados de grupo para dicha versión de objeto.
Al igual que todos los demás valores de bloqueo de objeto, la fecha de retención hasta se aplica a las versiones de objeto individuales. Las diferentes versiones de un solo objeto pueden tener diferentes modalidades de retención y periodos.
Imagine un objeto que tenga 60 días en un periodo de retención de 90 días y sobrescriba ese objeto con el mismo nombre y un periodo de retención de dos años. La operación se realizará correctamente y se creará una nueva versión del objeto con un periodo de retención de dos años. Mientras tanto, después de 30 días más la versión original es elegible para la supresión.
Ampliación de un periodo de retención
Para ampliar el periodo de retención de un objeto, simplemente envíe una solicitud para establecer un nuevo periodo de retención más largo. El valor antiguo se sobrescribirá con el nuevo, suponiendo que el solicitante tenga las acciones cloud-object-storage.object.put_object_lock_retention y cloud-object-storage.object.put_object_lock_retention_version.
Reducción del período de retención
Para los objetos protegidos en modo GOVERNANCE, los usuarios autorizados pueden reducir el periodo de retención a una fecha anterior, siempre que incluyan el x-amz-bypass-governance-retention encabezado en la solicitud y dispongan
de los permisos adecuados (cloud-object-storage.object.bypass_governance_retention, cloud-object-storage.object.put_object_lock_retention y cloud-object-storage.object.put_object_lock_retention_version).
Los objetos en modo CUMPLIMIENTO no pueden ver reducido o eliminado su período de retención antes de que expire la fecha de retención.
Retención legal
Una retención legal es como un periodo de retención en el sentido de que impide que se sobrescriba o se suprima una versión de objeto. Sin embargo, las retenciones legales son más flexibles y no tienen un componente temporal definido.
En cambio, simplemente permanecen en vigor hasta que se eliminan. Las retenciones legales pueden ser colocadas y eliminadas libremente por cualquier usuario que tenga las acciones cloud-object-storage.object.put_object_lock_legal_hold y cloud-object-storage.object.put_object_lock_legal_hold_version.
Las retenciones legales tienen el beneficio adicional de actuar como método para aplicar la retención indefinida sobre un objeto.
Las retenciones legales y los períodos de retención funcionan de forma independiente. Las retenciones legales no tienen ningún impacto en los períodos de retención, y viceversa.
Imagine un objeto con una retención legal y un periodo de retención. Cuando finaliza el periodo de retención, la versión del objeto permanece protegida hasta que se elimina la retención legal. Si elimina una retención legal mientras una versión de objeto está sujeta a un periodo de retención, permanece protegida hasta que se completa el periodo de retención.
Los objetos bloqueados y almacenados con un periodo de retención no se pueden suprimir hasta que caduque el periodo de retención y se elimine cualquier retención legal asociada. Sin embargo, en el caso de los objetos bloqueados en modo GOVERNANCE,
los usuarios autorizados con el bypass-governance-retention permiso pueden eliminar el objeto antes de que expire el período de retención, siempre que no haya ninguna retención legal activa sobre el objeto.
Introducción a Object Lock
Para empezar, existen algunos requisitos previos:
- Necesitará el rol de plataforma
WriteroManageren un grupo, o un rol personalizado con las acciones adecuadas (comocloud-object-storage.bucket.put_object_lock_configuration) asignadas. - El mantenimiento de versiones de objetos debe estar habilitado
- Deberá utilizar el plan de precios estándar; consulte precios para obtener más detalles.
- Tendrá que elegir una región en la que se admita el bloqueo de objetos, consulte Servicios integrados para obtener más detalles.
- Se da soporte a un periodo máximo de retención predeterminado de 100 años (o 36500 días).
- Al utilizar la consola, también es posible establecer una Fecha de retención hasta en meses, además de días o años.
En el modo COMPLIANCE, no se puede reducir el período de retención de un objeto. En el modo GOVERNANCE, los usuarios autorizados con el permiso BypassGovernanceRetention pueden reducir o eliminar la retención si es necesario. Para las pruebas de validación, se recomienda utilizar una retención predeterminada más corta (por ejemplo, 1 día) y ajustarla según sea necesario.
Creación y configuración del nuevo grupo para utilizarlo con Object Lock
- Vaya a la instancia de Object Storage deseada y utilice Crear grupo con Personalizar la opción de grupo
- Especifique los detalles de configuración de grupo necesarios según sus requisitos de caso de uso
- Vaya a la sección Object Versioning y establézcalo en Enabled
- Busque Inmutabilidad y, en Bloqueo de objeto, pulse Añadir
- Establecer bloqueo de objeto en Habilitado
- Opcionalmente, establezca un periodo de retención predeterminado.
- Pulse Guardar
- Continúe con el resto de los valores de configuración y pulse Crear grupo
Habilitación del bloqueo de objeto en un grupo existente:
Se puede establecer un grupo para el uso de bloqueo de objeto como se indica a continuación:
- Vaya a la sección Configuración del grupo
- Pulse Object Versioning
- En la sección Object Versioning , pulse Editar, establezca la opción de configuración en Habilitado y Guardar
- Vaya a la sección Bloqueo de objeto y pulse Añadir
- Establezca Bloqueo de objeto en Habilitado
- Opcionalmente, establezca un periodo de retención predeterminado.
- Haga clic en Guardar.
Adición de una retención hasta la fecha o una retención legal a un objeto
- Vaya al grupo con el objeto de destino
- Conmutar Versiones de visualización
- Ir a los detalles de la versión de destino
- Añada un periodo de retención y/o active una retención legal.
Utilización del bloqueo de objetos para la continuidad del negocio y la recuperación tras desastre
Object Lock se puede utilizar para proporcionar continuidad de servicio en caso de un ataque de ransomware, ya que los datos protegidos no se pueden modificar o destruir.
Coherencia e integridad de datos
Mientras que IBM Cloud Object Storage proporciona una fuerte consistencia para todas las operaciones de IO de datos, la configuración de los cubos es finalmente consistente. Después de habilitar, modificar o suprimir un periodo de retención predeterminado en un grupo, la configuración puede tardar unos minutos en propagarse por el sistema. Las operaciones sobre objetos, como la adición de una retención legal, son inmediatamente coherentes.
Uso y contabilidad
Los objetos bloqueados (y sus versiones) contribuyen al uso igual que cualquier otro dato y el usuario será responsable de los costes de uso mientras el objeto permanezca bloqueado con un periodo de retención.
Interacciones
Object Lock se puede utilizar en combinación con varias características de almacenamiento de objetos según sus requisitos de caso de uso.
Mantenimiento de versiones
Habilitación del mantenimiento de versiones es un requisito previo para habilitar el bloqueo de objetos. Si se crea un grupo utilizando la cabecera x-amz-bucket-object-lock-enabled,
el mantenimiento de versiones se habilitará automáticamente.
La supresión de un objeto con versión crea un marcador de supresión. El objeto puede parecer eliminado, pero si está protegido, es imposible eliminar la versión protegida en el modo COMPLIANCE. Los propios marcadores de supresión
no están protegidos. Sin embargo, en el caso de los objetos bloqueados en modo GOVERNANCE, los usuarios autorizados con el bypass-governance-retention permiso pueden eliminar el objeto antes de que expire el período de retención,
siempre que no haya ninguna retención legal activa sobre el objeto.
Réplica
El bloqueo de objeto no se puede utilizar en el grupo de origen para la réplica, sólo en el destino. A los objetos se les asignará el periodo de retención predeterminado.
Sistemas de gestión de claves
Los objetos protegidos se cifrarán utilizando la clave raíz del grupo. Cuando el bloqueo de objeto está habilitado en un grupo, la clave raíz alojada por Key Protect o Hyper Protect Crypto Services está protegida contra supresión siempre que un grupo asociado tenga el bloqueo de objeto habilitado. Esto impide la destrucción criptográfica de objetos protegidos.
Configuraciones de ciclo de vida
Es posible habilitar las políticas de ciclo de vida que archivan objetos bloqueados, pero naturalmente no las que caducan objetos bajo retención o retención legal (los objetos no protegidos en el grupo todavía pueden caducar).
Immutable Object Storage
Object Lock es una alternativa a las políticas de retención disponibles cuando se utiliza Object Storageinmutable. Puesto que el bloqueo de objetos requiere que se habilite el mantenimiento de versiones, y el Object Storage inmutable no es compatible con el mantenimiento de versiones, es imposible tener ambas soluciones WORM habilitadas en el mismo grupo. Es posible tener una combinación de grupos en una instancia de servicio, cada uno utilizando Object Storage inmutable o Bloqueo de objetos.
Etiquetado de objetos
No hay restricciones en la adición o modificación de etiquetas en un objeto protegido.
Otras interacciones
No debe haber interacciones adversas al utilizar Object Lock con otras características de Object Storage, como por ejemplo establecer políticas de CORS, establecer cortafuegos de IP o restricciones basadas en condiciones, cuotas de grupo o Code Engine.
Acciones de IAM
Hay nuevas acciones de IAM asociadas con el bloqueo de objeto.
| Acción IAM | Rol |
|---|---|
cloud-object-storage.bucket.get_object_lock_configuration |
Gestor, Escritor, Lector |
cloud-object-storage.bucket.put_object_lock_configuration |
Gestor, Escritor |
cloud-object-storage.object.get_object_lock_retention |
Gestor, Escritor, Lector |
cloud-object-storage.object.put_object_lock_retention |
Gestor, Escritor |
cloud-object-storage.object.get_object_lock_retention_version |
Gestor, Escritor, Lector |
cloud-object-storage.object.put_object_lock_retention_version |
Gestor, Escritor |
cloud-object-storage.object.get_object_lock_legal_hold |
Gestor, Escritor, Lector |
cloud-object-storage.object.put_object_lock_legal_hold |
Gestor, Escritor |
cloud-object-storage.object.get_object_lock_legal_hold_version |
Gestor, Escritor, Lector |
cloud-object-storage.object.put_object_lock_legal_hold_version |
Gestor, Escritor |
cloud-object-storage.object.bypass_governance_retention |
Gestor, Escritor |
Tenga en cuenta que los usuarios con el rol de Escritor son capaces de hacer que los objetos no se puedan suprimir durante muchos años (posiblemente miles de años). Tenga cuidado y considere la posibilidad de crear roles personalizados que no permitan a la mayoría de los usuarios establecer una fecha de retención hasta.
Sucesos de Activity Tracker
El bloqueo de objeto genera sucesos adicionales.
cloud-object-storage.bucket-object-lock.createcloud-object-storage.bucket-object-lock.readcloud-object-storage.object-object-lock-legal-hold.createcloud-object-storage.object-object-lock-legal-hold.readcloud-object-storage.object-object-lock-retention.createcloud-object-storage.object-object-lock-retention.read
Para sucesos de cloud-object-storage.bucket-object-lock.create, los campos siguientes proporcionan información adicional:
| Campo | Descripción |
|---|---|
requestData.object_lock_configuration.enabled |
Indica que el bloqueo de objeto está habilitado en el grupo |
requestData.object_lock_configuration.defaultRetention.mode |
Indica que el COMPLIANCE modo GOVERNANCE o está activo. |
object_lock_configuration.defaultRetention.years |
El periodo de retención predeterminado en años. |
object_lock_configuration.defaultRetention.days |
El periodo de retención predeterminado en días. |
Sólo estarán presentes object_lock_configuration.defaultRetention.years o object_lock_configuration.defaultRetention.days, pero no ambos al mismo tiempo.
Para las operaciones en objetos protegidos, pueden estar presentes los campos siguientes:
| Campo | Descripción |
|---|---|
requestData.object_lock_protection.legal_hold |
Indica que hay una retención legal en vigor en la versión del objeto. |
requestData.object_lock_protection.retention.mode |
Indica COMPLIANCE que GOVERNANCE el modo está activo en la versión del objeto. |
requestData.object_lock_protection.retention.retain_until_date |
Indica la fecha en la que la versión del objeto es elegible para su supresión. Después de esta fecha, el objeto ya no se suprime protegido en función de una fecha de retención. |
Ejemplos de API REST
Los ejemplos siguientes se muestran utilizando cURL para facilitar su uso. Las variables de entorno se utilizan para representar elementos específicos del usuario como, por ejemplo, $BUCKET, $TOKEN y $REGION.
Tenga en cuenta que $REGION también incluiría cualquier especificación de tipo de red, por lo que el envío de una solicitud a un grupo en us-south utilizando la red privada requeriría establecer la variable en private.us-south.
Habilitar bloqueo de objeto en un grupo
La configuración de bloqueo de objeto se proporciona como XML en el cuerpo de la solicitud. Las nuevas solicitudes sobrescribirán las reglas de réplica existentes que estén presentes en el grupo.
Una configuración de bloqueo de objeto debe incluir una regla.
| Cabecera | Tipo | Descripción |
|---|---|---|
Content-MD5 |
Serie | El hash 128-bit MD5 codificado con el algoritmo de hash de bloque ( base64 ) de la carga útil, que se utiliza como comprobación de integridad para garantizar que la carga útil no se ha alterado durante la transmisión. |
x-amz-checksum-crc32 |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32 codificada en Base64 del objeto. |
x-amz-checksum-crc32c |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32C codificada en Base64 del objeto. |
x-amz-checksum-crc64nvme |
Serie | Esta cabecera es la suma de comprobación de 64 bits CRC64NVME codificada en Base64 del objeto. La suma de comprobación de CRC64NVME es siempre una suma de comprobación de objeto completo. |
x-amz-checksum-sha1 |
Serie | Este encabezado es el Base64 codificado, 160-bit SHA1 digest del objeto. |
x-amz-checksum-sha256 |
Serie | Este encabezado es el Base64 codificado, 256-bit SHA256 digest del objeto. |
x-amz-sdk-checksum-algorithm |
Serie | Indica el algoritmo utilizado para crear la suma de comprobación del objeto cuando se utiliza el SDK. |
x-amz-bypass-governance-retention |
Serie | Este encabezado permite a los usuarios autorizados anular la configuración de retención del modo GOVERNANCE para eliminar o modificar un objeto antes de su fecha de retención. |
Se requiere un encabezado Content-MD5 o un encabezado checksum (incluyendo x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1,
o x-amz-checksum-sha256) como comprobación de integridad para la carga útil.
El cuerpo de la solicitud debe contener un bloque XML con el esquema siguiente:
| Elemento | Tipo | Hijos | Predecesor | Restricción |
|---|---|---|---|---|
ObjectLockConfiguration |
Contenedor | ObjectLockEnabled, Rule |
Ninguna | Necesario Límite 1. |
ObjectLockEnabled |
Serie | Ninguna | ObjectLockConfiguration |
Necesario El único valor válido es Enabled (sensible a mayúsculas y minúsculas). |
Rule |
Contenedor | DefaultRetention |
ObjectLockConfiguration |
Límite 1 |
DefaultRetention |
Contenedor | Days, Mode, Years |
Rule |
Límite 1. |
Days |
Entero | Ninguna | DefaultRetention |
El número de días que desea especificar para el periodo de retención predeterminado. No se puede combinar con Years. |
Mode |
Serie | Ninguna | DefaultRetention |
COMPLIANCE o GOVERNANCE (distingue entre mayúsculas y minúsculas). |
Years |
Entero | Ninguna | DefaultRetention |
El número de años que desea especificar para el periodo de retención predeterminado. No se puede combinar con Days. |
Este ejemplo conservará los objetos nuevos durante al menos 30 días.
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>'
Una solicitud correcta devuelve una respuesta 200.
Ver la configuración de bloqueo de objetos para un depósito
curl -X "GET" "https://$BUCKET.s3.$REGION.cloud-object-storage.appdomain.cloud/?object-lock" \
-H 'Authorization: bearer $TOKEN'
Esto devuelve un cuerpo de respuesta XML con el esquema adecuado:
<ObjectLockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<ObjectLockEnabled>string</ObjectLockEnabled>
<Rule>
<DefaultRetention>
<Days>30</Days>
<Mode>COMPLIANCE</Mode>
</DefaultRetention>
</Rule>
</ObjectLockConfiguration>
Añadir o ampliar un periodo de retención para un objeto
La configuración de bloqueo de objeto se proporciona como XML en el cuerpo de la solicitud. Las nuevas solicitudes sobrescribirán cualquier regla de replicación existente que esté presente en el objeto, siempre que el RetainUntilDate esté más lejos en el futuro que el valor actual, o si el objeto está bloqueado en modo GOVERNANCE y el solicitante tiene el bypass-governance-retention permiso.
| Cabecera | Tipo | Descripción |
|---|---|---|
Content-MD5 |
Serie | El hash 128-bit MD5 codificado con el algoritmo de hash de bloque ( base64 ) de la carga útil, que se utiliza como comprobación de integridad para garantizar que la carga útil no se ha alterado durante la transmisión. |
x-amz-checksum-crc32 |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32 codificada en Base64 del objeto. |
x-amz-checksum-crc32c |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32C codificada en Base64 del objeto. |
x-amz-checksum-crc64nvme |
Serie | Esta cabecera es la suma de comprobación de 64 bits CRC64NVME codificada en Base64 del objeto. La suma de comprobación de CRC64NVME es siempre una suma de comprobación de objeto completo. |
x-amz-checksum-sha1 |
Serie | Este encabezado es el Base64 codificado, 160-bit SHA1 digest del objeto. |
x-amz-checksum-sha256 |
Serie | Este encabezado es el Base64 codificado, 256-bit SHA256 digest del objeto. |
x-amz-sdk-checksum-algorithm |
Serie | Indica el algoritmo utilizado para crear la suma de comprobación del objeto cuando se utiliza el SDK. |
x-amz-bypass-governance-retention |
Serie | Este encabezado permite a los usuarios autorizados anular la configuración de retención del modo GOVERNANCE para eliminar o modificar un objeto antes de su fecha de retención. |
Se requiere un encabezado Content-MD5 o un encabezado checksum (incluyendo x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1,
o x-amz-checksum-sha256) como comprobación de integridad para la carga útil.
Opcionalmente, puede especificar la versión a la que aplicar el RetainUntilDate.
Parámetros de consulta opcionales
| Parámetro | ¿Obligatorio? | Tipo | Descripción |
|---|---|---|---|
versionID |
Opcional | string | ID de versión. |
El cuerpo de la solicitud debe contener un bloque XML con el esquema siguiente:
| Elemento | Tipo | Hijos | Predecesor | Restricción |
|---|---|---|---|---|
Retention |
Contenedor | Mode, RetainUntilDate |
Ninguna | Necesario Límite 1. |
Mode |
Serie | Ninguna | Retention |
**Obligatorio **COMPLIANCE o GOVERNANCE (distingue entre mayúsculas y minúsculas). |
RetainUntilDate |
Serie | Ninguna | Retention |
Necesario Fecha después de la cual un objeto es elegible para su supresión en el formato de fecha y hora ISO8601. |
Este ejemplo conservará cualquier objeto nuevo durante al menos hasta el 12 de marzo de 2023.
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>'
Una solicitud correcta devuelve una respuesta 200.
Si los valores de RetainUntilDate no superan ningún valor existente, la operación fallará con un 403 Access Denied.
Este ejemplo acorta el período de retención de una versión de objeto existente protegida en modo GOVERNANCE. El solicitante debe tener el permiso de omisión-gobernanza-retención.
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>'
Una solicitud exitosa devuelve una respuesta 200 OK. Si el solicitante no tiene el bypass-governance-retention permiso o se omite el encabezado, la operación fallará con un 403 Acceso denegado.
Añadir o eliminar una retención legal para un objeto
La configuración de bloqueo de objeto se proporciona como XML en el cuerpo de la solicitud. Las nuevas solicitudes sobrescribirán las reglas de réplica existentes que estén presentes en el objeto, siempre que el RetainUntilDate esté más lejos en el futuro que el valor actual.
| Cabecera | Tipo | Descripción |
|---|---|---|
Content-MD5 |
Serie | El hash 128-bit MD5 codificado con el algoritmo de hash de bloque ( base64 ) de la carga útil, que se utiliza como comprobación de integridad para garantizar que la carga útil no se ha alterado durante la transmisión. |
x-amz-checksum-crc32 |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32 codificada en Base64 del objeto. |
x-amz-checksum-crc32c |
Serie | Esta cabecera es la suma de comprobación de 32 bits CRC32C codificada en Base64 del objeto. |
x-amz-checksum-crc64nvme |
Serie | Esta cabecera es la suma de comprobación de 64 bits CRC64NVME codificada en Base64 del objeto. La suma de comprobación de CRC64NVME es siempre una suma de comprobación de objeto completo. |
x-amz-checksum-sha1 |
Serie | Este encabezado es el Base64 codificado, 160-bit SHA1 digest del objeto. |
x-amz-checksum-sha256 |
Serie | Este encabezado es el Base64 codificado, 256-bit SHA256 digest del objeto. |
x-amz-sdk-checksum-algorithm |
Serie | Indica el algoritmo utilizado para crear la suma de comprobación del objeto cuando se utiliza el SDK. |
Se requiere un encabezado Content-MD5 o un encabezado checksum (incluyendo x-amz-checksum-crc32, x-amz-checksum-crc32c, x-amz-checksum-crc64nvme, x-amz-checksum-sha1,
o x-amz-checksum-sha256) como comprobación de integridad para la carga útil.
El cuerpo de la solicitud debe contener un bloque XML con el esquema siguiente:
| Elemento | Tipo | Hijos | Predecesor | Restricción |
|---|---|---|---|---|
legal-hold |
Contenedor | Status |
Ninguna | Límite 1. |
Status |
Serie | Ninguna | legal-hold |
Los valores soportados son ON o OFF (sensible a mayúsculas y minúsculas) |
Este ejemplo conservará cualquier objeto nuevo durante al menos hasta el 12 de marzo de 2023.
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>'
Una solicitud correcta devuelve una respuesta 200.
Ejemplos de SDK
Los siguientes ejemplos utilizan los SDK COS de IBM para Python, Node.js, Java y Go, así como un script de Terraform, aunque la implementación del control de versiones de objetos debería ser totalmente compatible con cualquier biblioteca o herramienta de S3-compatible que permita la configuración de puntos finales personalizados. El uso de herramientas de terceros requiere credenciales HMAC para calcular las firmas AWS V4.
Python
La habilitación del bloqueo de objetos utilizando el SDK de IBM COS para Python se puede realizar utilizando la sintaxis de cliente de bajo nivel.
Utilización de un cliente:
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
Habilitación del mantenimiento de versiones utilizando 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
}