Lab práctico · Semana 8: Gobierno, cumplimiento e IA responsable
Auditoría y gobierno con model invocation logging, CloudTrail y model cards
Qué vas a construir
La «caja negra» de una aplicación de IA generativa: todo lo que un auditor, un regulador o tu equipo de seguridad te pedirá demostrar.
- Model invocation logging de Amazon Bedrock hacia CloudWatch Logs y S3: registro completo de cada prompt, cada respuesta, el modelo, la identidad que llamó y los tokens.
- Una política de protección de datos de CloudWatch Logs que enmascara emails en esos logs (redacción a nivel de token para quien no tenga permiso
logs:Unmask). - Metadatos por petición (
requestMetadata) para atribuir cada invocación a un equipo y a un caso de uso. - Un trail de AWS CloudTrail con eventos de gestión y data events de guardrails y knowledge bases: quién hizo qué, cuándo y desde dónde.
- Consultas de auditoría con CloudWatch Logs Insights.
- Una alarma automática cuando un guardrail interviene demasiadas veces (posible abuso).
- Una SageMaker model card que documenta el uso del modelo, su riesgo y sus limitaciones (transparencia, IA responsable).
flowchart LR
APP["App (Converse + requestMetadata)"] --> BR["Amazon Bedrock"]
BR -- "prompts y respuestas" --> CWL["CloudWatch Logs (emails enmascarados)"]
BR -- "prompts y respuestas" --> S3L["S3: BedrockModelInvocationLogs"]
BR -- "quién, qué, cuándo" --> CT["CloudTrail trail"]
CT --> S3T["S3 del trail"]
GR["Guardrail"] -- "InvocationsIntervened" --> AL["Alarma CloudWatch"] --> SNS["Tema SNS"]
MC["SageMaker model card"] -.-> AUD["Auditoría y cumplimiento"]
CWL --> LI["Logs Insights"]
La diferencia clave que busca el examen: CloudTrail registra la llamada a la API (identidad, IP, operación, modelo, hora) pero no el contenido del prompt ni de la respuesta; el model invocation logging registra el contenido completo. Para auditar «qué se preguntó y qué contestó el modelo» necesitas el segundo; para «quién borró el guardrail», el primero.
Antes de empezar
- Región eu-central-1 y AWS CloudShell con permisos de administrador. Sin claves en ficheros.
- El model invocation logging es por cuenta y región y está desactivado por defecto. Si ya lo tienes activado en eu-central-1, anota tu configuración actual (
aws bedrock get-model-invocation-logging-configuration) porque este lab la reemplaza y la limpieza la borra. - Coste: tokens de Nova Micro (céntimos), almacenamiento mínimo en S3 y CloudWatch Logs, y data events de CloudTrail, que se cobran aparte de los eventos de gestión (consulta los precios de CloudTrail). Con unas decenas de llamadas, el total queda en céntimos.
mkdir -p ~/lab15 && cd ~/lab15
export AWS_REGION=eu-central-1
export AWS_DEFAULT_REGION=eu-central-1
export CUENTA=$(aws sts get-caller-identity --query Account --output text)
export BUCKET_LOGS="lab15-invocaciones-${CUENTA}"
export BUCKET_TRAIL="lab15-cloudtrail-${CUENTA}"
export LOG_GROUP="/lab15/bedrock/invocaciones"
Paso 1: destinos del model invocation logging
Bucket S3
Los destinos deben estar en la misma cuenta y región que la configuración de logging. La política permite a Bedrock escribir solo bajo AWSLogs/CUENTA/BedrockModelInvocationLogs/, y solo en nombre de tu cuenta (condiciones aws:SourceAccount y aws:SourceArn, que evitan el problema del confused deputy).
aws s3api create-bucket --bucket "$BUCKET_LOGS" \
--create-bucket-configuration LocationConstraint=eu-central-1
aws s3api put-public-access-block --bucket "$BUCKET_LOGS" \
--public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
cat > politica-bucket-logs.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AmazonBedrockLogsWrite",
"Effect": "Allow",
"Principal": {"Service": "bedrock.amazonaws.com"},
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::${BUCKET_LOGS}/AWSLogs/${CUENTA}/BedrockModelInvocationLogs/*"],
"Condition": {
"StringEquals": {"aws:SourceAccount": "${CUENTA}"},
"ArnLike": {"aws:SourceArn": "arn:aws:bedrock:eu-central-1:${CUENTA}:*"}
}
}]
}
EOF
aws s3api put-bucket-policy --bucket "$BUCKET_LOGS" --policy file://politica-bucket-logs.json
Log group y rol para CloudWatch Logs
aws logs create-log-group --log-group-name "$LOG_GROUP"
aws logs put-retention-policy --log-group-name "$LOG_GROUP" --retention-in-days 7
cat > confianza-bedrock.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "bedrock.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "${CUENTA}"},
"ArnLike": {"aws:SourceArn": "arn:aws:bedrock:eu-central-1:${CUENTA}:*"}
}
}]
}
EOF
cat > permisos-logs.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:eu-central-1:${CUENTA}:log-group:${LOG_GROUP}:log-stream:aws/bedrock/modelinvocations"
}]
}
EOF
aws iam create-role --role-name lab15-bedrock-logging \
--assume-role-policy-document file://confianza-bedrock.json
aws iam put-role-policy --role-name lab15-bedrock-logging \
--policy-name escribir-logs --policy-document file://permisos-logs.json
export ROL_LOGS=$(aws iam get-role --role-name lab15-bedrock-logging --query Role.Arn --output text)
Paso 2: activar el model invocation logging
Activas solo la modalidad de texto. Los cuerpos de más de 100 KB (o binarios) no caben en CloudWatch Logs y se envían al bucket indicado en largeDataDeliveryS3Config.
cat > logging-config.json <<EOF
{
"cloudWatchConfig": {
"logGroupName": "${LOG_GROUP}",
"roleArn": "${ROL_LOGS}",
"largeDataDeliveryS3Config": {"bucketName": "${BUCKET_LOGS}", "keyPrefix": "grandes"}
},
"s3Config": {"bucketName": "${BUCKET_LOGS}", "keyPrefix": "invocaciones"},
"textDataDeliveryEnabled": true,
"imageDataDeliveryEnabled": false,
"embeddingDataDeliveryEnabled": false,
"videoDataDeliveryEnabled": false
}
EOF
sleep 10 # da tiempo a que el rol recién creado se propague
aws bedrock put-model-invocation-logging-configuration --logging-config file://logging-config.json
aws bedrock get-model-invocation-logging-configuration
Si recibes un error de validación sobre el rol, espera unos segundos y repite: IAM tarda un poco en propagar los roles nuevos.
Paso 3: enmascarar datos sensibles en CloudWatch Logs
Una data protection policy de CloudWatch Logs detecta datos sensibles con identificadores gestionados y los enmascara en todos los puntos de salida (consola, Logs Insights, filtros de métricas y de suscripción). Solo quien tenga logs:Unmask ve el valor original. Se aplica a lo que se ingiere después de crearla.
cat > proteccion-datos.json <<'EOF'
{
"Name": "lab15-proteccion",
"Description": "Enmascara emails en los logs de invocación",
"Version": "2021-06-01",
"Statement": [
{
"Sid": "auditar",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/EmailAddress"],
"Operation": {"Audit": {"FindingsDestination": {}}}
},
{
"Sid": "enmascarar",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/EmailAddress"],
"Operation": {"Deidentify": {"MaskConfig": {}}}
}
]
}
EOF
aws logs put-data-protection-policy --log-group-identifier "$LOG_GROUP" \
--policy-document file://proteccion-datos.json
Esta política protege CloudWatch Logs, no la copia de S3. En S3 la protección es cifrado, política de bucket, bloqueo de acceso público y, si hace falta inmutabilidad para auditoría, S3 Object Lock.
Paso 4: trail de CloudTrail con data events de Bedrock
Recuerda cómo registra CloudTrail las APIs de Bedrock:
InvokeModel,InvokeModelWithResponseStream,ConverseyConverseStreamson management events: se registran por defecto y aparecen en Event history (90 días) sin crear nada.ApplyGuardrail(incluidas las evaluaciones de guardrail durante la invocación),Retrieve/RetrieveAndGeneratede knowledge bases,InvokeFlow,InvokeAgenty otras son data events: no se registran por defecto, necesitan un trail con selectores avanzados y no aparecen en Event history, solo en el destino del trail.
aws s3api create-bucket --bucket "$BUCKET_TRAIL" \
--create-bucket-configuration LocationConstraint=eu-central-1
aws s3api put-public-access-block --bucket "$BUCKET_TRAIL" \
--public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
TRAIL_ARN="arn:aws:cloudtrail:eu-central-1:${CUENTA}:trail/lab15-trail"
cat > politica-bucket-trail.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::${BUCKET_TRAIL}",
"Condition": {"StringEquals": {"aws:SourceArn": "${TRAIL_ARN}"}}
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${BUCKET_TRAIL}/AWSLogs/${CUENTA}/*",
"Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control", "aws:SourceArn": "${TRAIL_ARN}"}}
}
]
}
EOF
aws s3api put-bucket-policy --bucket "$BUCKET_TRAIL" --policy file://politica-bucket-trail.json
aws cloudtrail create-trail --name lab15-trail --s3-bucket-name "$BUCKET_TRAIL" \
--enable-log-file-validation
aws cloudtrail put-event-selectors --trail-name lab15-trail --advanced-event-selectors '[
{
"Name": "Eventos de gestion",
"FieldSelectors": [{"Field": "eventCategory", "Equals": ["Management"]}]
},
{
"Name": "Data events de guardrails",
"FieldSelectors": [
{"Field": "eventCategory", "Equals": ["Data"]},
{"Field": "resources.type", "Equals": ["AWS::Bedrock::Guardrail"]}
]
},
{
"Name": "Data events de knowledge bases",
"FieldSelectors": [
{"Field": "eventCategory", "Equals": ["Data"]},
{"Field": "resources.type", "Equals": ["AWS::Bedrock::KnowledgeBase"]}
]
}
]'
aws cloudtrail start-logging --name lab15-trail
aws cloudtrail get-trail-status --name lab15-trail --query IsLogging
--enable-log-file-validation genera ficheros de resumen firmados que permiten demostrar que los logs no se han alterado: un requisito clásico de auditoría.
Paso 5: generar tráfico etiquetado
Crea un guardrail sencillo, solo con un word filter (gratuito), para generar data events y métricas:
export GID=$(aws bedrock create-guardrail --name lab15-simple \
--blocked-input-messaging "Petición bloqueada por la política de uso." \
--blocked-outputs-messaging "Respuesta bloqueada por la política de uso." \
--word-policy-config '{"wordsConfig":[{"text":"BancoRival"}]}' \
--query guardrailId --output text)
sleep 10
aws bedrock get-guardrail --guardrail-identifier "$GID" --query status
Ahora invoca Nova Micro varias veces con requestMetadata, unas etiquetas clave-valor que Bedrock copia tal cual en cada registro de invocación. Son la base para atribuir consumo y responsabilidad por equipo, aplicación o caso de uso (trazabilidad).
cat > trafico.py <<'EOF'
import boto3
rt = boto3.client("bedrock-runtime", region_name="eu-central-1")
MODELO = "eu.amazon.nova-micro-v1:0"
peticiones = [
("atencion-cliente", "faq", "¿Cuál es el horario de atención telefónica?"),
("atencion-cliente", "faq", "Mi email es cliente.prueba@example.com, ¿podéis escribirme?"),
("riesgos", "resumen", "Resume en una frase qué es el riesgo de crédito."),
("riesgos", "resumen", "Resume en una frase qué es el riesgo de liquidez."),
("marketing", "borrador", "Escribe un eslogan de 8 palabras para una cuenta sin comisiones."),
]
for equipo, caso, texto in peticiones:
r = rt.converse(
modelId=MODELO,
messages=[{"role": "user", "content": [{"text": texto}]}],
inferenceConfig={"maxTokens": 120},
requestMetadata={"equipo": equipo, "caso_uso": caso},
)
print(equipo, caso, r["usage"], "->", r["output"]["message"]["content"][0]["text"][:80])
EOF
python3 trafico.py
for i in 1 2 3 4 5 6; do
aws bedrock-runtime apply-guardrail --guardrail-identifier "$GID" --guardrail-version DRAFT \
--source INPUT --content '[{"text":{"text":"Me han dicho que BancoRival es mejor"}}]' \
--query action --output text
done
Paso 6: auditar con CloudTrail
Busca en Event history las llamadas de gestión a Bedrock:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=bedrock.amazonaws.com \
--max-results 10 \
--query "Events[].{hora:EventTime,evento:EventName,usuario:Username}" --output table
Verás Converse, CreateGuardrail, PutModelInvocationLoggingConfiguration… Abre uno completo para ver qué se registra:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Converse \
--max-results 1 --query "Events[0].CloudTrailEvent" --output text | python3 -m json.tool
Fíjate: identidad (userIdentity), IP, modelId en requestParameters, región… pero ni el prompt ni la respuesta. Si usas un perfil de inferencia, CloudTrail también indica en qué región se procesó la petición.
Los data events de ApplyGuardrail no están aquí: llegan al bucket del trail en unos minutos (hasta unos 15). Compruébalo más tarde:
aws s3 ls "s3://${BUCKET_TRAIL}/AWSLogs/${CUENTA}/CloudTrail/eu-central-1/" --recursive | tail -5
Descarga el fichero más reciente y busca ApplyGuardrail: verás eventCategory Data, el recurso AWS::Bedrock::Guardrail y en responseElements la acción y los assessments, sin el texto evaluado.
Paso 7: auditar el contenido con Logs Insights
Espera un par de minutos a que lleguen los logs y lanza consultas de CloudWatch Logs Insights. Primero, consumo de tokens por identidad:
cat > consulta1.txt <<'EOF'
fields identity.arn as principal, input.inputTokenCount as entrada, output.outputTokenCount as salida
| stats sum(entrada) as tokensEntrada, sum(salida) as tokensSalida, count() as llamadas by principal
EOF
QID=$(aws logs start-query --log-group-name "$LOG_GROUP" \
--start-time $(date -d '-1 hour' +%s) --end-time $(date +%s) \
--query-string "$(cat consulta1.txt)" --query queryId --output text)
sleep 5
aws logs get-query-results --query-id "$QID" --query results --output json
Después, por equipo y caso de uso gracias a requestMetadata:
cat > consulta2.txt <<'EOF'
fields requestMetadata.equipo as equipo, requestMetadata.caso_uso as caso
| stats count() as llamadas, sum(input.inputTokenCount) as entrada, sum(output.outputTokenCount) as salida by equipo, caso
| sort entrada desc
EOF
QID=$(aws logs start-query --log-group-name "$LOG_GROUP" \
--start-time $(date -d '-1 hour' +%s) --end-time $(date +%s) \
--query-string "$(cat consulta2.txt)" --query queryId --output text)
sleep 5
aws logs get-query-results --query-id "$QID" --query results --output json
Por último, comprueba el enmascarado: busca el registro con el email.
QID=$(aws logs start-query --log-group-name "$LOG_GROUP" \
--start-time $(date -d '-1 hour' +%s) --end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /escribirme/ | limit 1' \
--query queryId --output text)
sleep 5
aws logs get-query-results --query-id "$QID" --query "results[0]" --output json | head -c 1500
El email aparece enmascarado con asteriscos. En el objeto equivalente de S3 (bajo invocaciones/AWSLogs/...), en cambio, estará en claro.
Paso 8: alerta automática ante intervenciones del guardrail
Un pico de intervenciones puede indicar un usuario intentando jailbreaks o una fuga de datos. Crea un tema SNS y una alarma sobre InvocationsIntervened en el namespace AWS/Bedrock/Guardrails:
export TOPIC=$(aws sns create-topic --name lab15-alertas-ia --query TopicArn --output text)
# Opcional: recibe el aviso por correo (confirma la suscripción en tu email)
# aws sns subscribe --topic-arn "$TOPIC" --protocol email --notification-endpoint tu-correo@example.com
aws cloudwatch put-metric-alarm \
--alarm-name lab15-intervenciones-guardrail \
--alarm-description "Demasiadas intervenciones del guardrail en 5 minutos" \
--namespace AWS/Bedrock/Guardrails \
--metric-name InvocationsIntervened \
--dimensions Name=Operation,Value=ApplyGuardrail \
--statistic Sum --period 300 --evaluation-periods 1 \
--threshold 5 --comparison-operator GreaterThanOrEqualToThreshold \
--treat-missing-data notBreaching \
--alarm-actions "$TOPIC"
aws cloudwatch describe-alarms --alarm-names lab15-intervenciones-guardrail \
--query "MetricAlarms[0].StateValue"
Con las seis intervenciones del paso 5, la alarma debería pasar a ALARM en unos minutos. Si se queda en INSUFFICIENT_DATA, es que la métrica se publica con otra combinación de dimensiones: ejecuta aws cloudwatch list-metrics --namespace AWS/Bedrock/Guardrails --metric-name InvocationsIntervened y recrea la alarma con las dimensiones exactas que aparezcan. En producción, el tema SNS podría disparar una Lambda de remediación (por ejemplo, revocar temporalmente la sesión del usuario o abrir un ticket).
Paso 9: documentar el modelo con una model card
Las SageMaker model cards documentan en un solo lugar el propósito, los usos previstos y no previstos, la valoración de riesgo, las evaluaciones y las consideraciones éticas de un modelo. Cada edición (salvo el cambio de estado) crea una versión nueva, lo que deja un registro inmutable, y se pueden exportar a PDF para auditores. Aunque nacieron para modelos entrenados en SageMaker AI, sirven para documentar el uso de un modelo fundacional de Bedrock en tu aplicación.
cat > tarjeta.json <<'EOF'
{
"model_overview": {
"model_description": "Uso de Amazon Nova Micro (perfil eu.amazon.nova-micro-v1:0) para responder preguntas frecuentes de clientes de BancoLab.",
"model_creator": "Amazon (modelo fundacional en Amazon Bedrock)",
"model_owner": "Equipo de atención al cliente de BancoLab",
"problem_type": "Generación de texto"
},
"intended_uses": {
"purpose_of_model": "Responder preguntas frecuentes no personalizadas sobre productos y horarios.",
"intended_uses": "FAQ con fuentes internas mediante RAG y guardrail obligatorio. No apto para asesoramiento financiero, decisiones de crédito ni datos personales sin anonimizar.",
"factors_affecting_model_efficiency": "Calidad y actualidad de los documentos recuperados; idioma; longitud del contexto.",
"risk_rating": "Medium",
"explanations_for_risk_rating": "Contacto directo con clientes; riesgo de alucinaciones mitigado con contextual grounding y revisión humana de reclamaciones."
},
"additional_information": {
"ethical_considerations": "Se evalúa periódicamente el sesgo en las respuestas por idioma y perfil de cliente. El usuario es informado de que habla con un sistema de IA.",
"caveats_and_recommendations": "Puede generar información incorrecta. Mostrar siempre las fuentes citadas y ofrecer paso a un agente humano."
}
}
EOF
aws sagemaker create-model-card \
--model-card-name lab15-faq-nova-micro \
--model-card-status Draft \
--content file://tarjeta.json
aws sagemaker update-model-card \
--model-card-name lab15-faq-nova-micro \
--model-card-status PendingReview
aws sagemaker describe-model-card --model-card-name lab15-faq-nova-micro \
--query "{estado:ModelCardStatus,version:ModelCardVersion,creada:CreationTime}"
El flujo Draft → PendingReview → Approved (→ Archived) es tu proceso de aprobación: puedes exigir que ninguna aplicación pase a producción sin una model card aprobada, y comprobarlo en el pipeline de CI/CD.
Comprueba que funciona
get-model-invocation-logging-configurationmuestra los dos destinos y solo texto activado.- En el log group aparecen registros con
schemaTypeModelInvocationLog,modelId,identity.arn,requestMetadatay recuento de tokens. - El email del paso 5 aparece enmascarado en CloudWatch Logs.
lookup-eventsmuestra eventosConversesin contenido del prompt, y el bucket del trail acaba recibiendo data eventsApplyGuardrail.- Las consultas de Logs Insights agregan tokens por identidad y por equipo.
- La alarma existe y pasa a
ALARMtras las intervenciones. - La model card está en
PendingReview.
Limpieza
En este orden:
cd ~/lab15
# 1. Dejar de registrar invocaciones
aws bedrock delete-model-invocation-logging-configuration
# 2. CloudTrail
aws cloudtrail stop-logging --name lab15-trail
aws cloudtrail delete-trail --name lab15-trail
# 3. Alarma y SNS
aws cloudwatch delete-alarms --alarm-names lab15-intervenciones-guardrail
aws sns delete-topic --topic-arn "$TOPIC"
# 4. Model card y guardrail
aws sagemaker delete-model-card --model-card-name lab15-faq-nova-micro
aws bedrock delete-guardrail --guardrail-identifier "$GID"
# 5. Política de protección de datos y log group
aws logs delete-data-protection-policy --log-group-identifier "$LOG_GROUP"
aws logs delete-log-group --log-group-name "$LOG_GROUP"
# 6. Rol de logging
aws iam delete-role-policy --role-name lab15-bedrock-logging --policy-name escribir-logs
aws iam delete-role --role-name lab15-bedrock-logging
# 7. Vaciar y borrar buckets
aws s3 rm "s3://${BUCKET_LOGS}" --recursive
aws s3api delete-bucket --bucket "$BUCKET_LOGS"
aws s3 rm "s3://${BUCKET_TRAIL}" --recursive
aws s3api delete-bucket --bucket "$BUCKET_TRAIL"
cd ~ && rm -rf ~/lab15
Si antes del lab tenías tu propia configuración de invocation logging, vuelve a aplicarla con put-model-invocation-logging-configuration.
Preguntas para pensar como arquitecto
- Un regulador pide conservar durante cinco años, de forma inalterable, todas las preguntas y respuestas de un chatbot, pero el equipo de soporte no debe ver datos personales. ¿Qué diseñas?
Respuesta
Model invocation logging a S3 con cifrado SSE-KMS de clave propia, S3 Object Lock en modo compliance y reglas de ciclo de vida hacia clases de almacenamiento baratas; acceso a ese bucket solo para el rol de auditoría. Para el día a día, el destino de CloudWatch Logs con retención corta y una data protection policy que enmascare PII, sin conceder logs:Unmask al equipo de soporte. CloudTrail con validación de integridad para demostrar quién accedió y cambió la configuración.
- Finanzas quiere saber cuánto gasta en tokens cada unidad de negocio que comparte la misma cuenta y el mismo rol. ¿Qué harías?
Respuesta
Añadir requestMetadata (unidad de negocio, aplicación, caso de uso) en cada llamada desde la capa de acceso común (por ejemplo, la Lambda del gateway de IA) y agregar los tokens por esas claves con Logs Insights o Athena sobre los logs de invocación. Si cada unidad usara su propio rol, bastaría agrupar por identity.arn.
- Tras un incidente, necesitas saber quién desactivó un guardrail el martes por la noche y si después hubo respuestas dañinas. ¿Qué fuentes cruzas?
Respuesta
CloudTrail (evento de gestión UpdateGuardrail o DeleteGuardrail, con identidad, IP y hora; GuardDuty también puede señalar este tipo de actividad sospechosa) y, para el contenido posterior, los model invocation logs de esa franja. Las métricas de AWS/Bedrock/Guardrails muestran la caída de intervenciones.
- ¿Por qué no basta con activar CloudTrail para cumplir un requisito de «trazabilidad de las decisiones del modelo»?
Respuesta
Porque CloudTrail no guarda el contenido: sabes que alguien llamó a Converse, pero no qué pidió, qué fuentes se usaron ni qué respondió el modelo. Hacen falta los model invocation logs (entrada, salida, tokens), las citas de las fuentes en RAG, las trazas de agentes y la documentación del modelo (model card) para reconstruir y justificar una decisión.