Logging, Field Masking & Signed Cookies
Why this matters in production
Hai chủ đề trong file này trông rời rạc nhưng chung một sợi chỉ: quan sát và kiểm soát truy cập ở edge, mà không tự tạo ra rủi ro mới.
- Logging là cách duy nhất bạn thấy Cloud Armor đang làm gì — rule nào khớp, request nào bị chặn, false positive ở đâu. Không có log đúng, mọi tuning (file 02) đều là mò mẫm. Nhưng logging — đặc biệt verbose logging — có thể vô tình ghi dữ liệu nhạy cảm của user vào log, biến công cụ debug thành lỗ hổng compliance.
- Signed cookies/URLs là cách kiểm soát truy cập tài nguyên ở edge (qua Cloud CDN) cho custom domain — cấp quyền truy cập giới hạn thời gian mà không cần backend xác thực từng request.
Điểm cốt lõi: verbose logging là con dao hai lưỡi mà rất nhiều team bật rồi quên, để lộ query/header chứa token, password, PII trong Cloud Logging suốt nhiều tháng. Hiểu chính xác cái gì được ghi và khi nào là vấn đề bảo mật thực sự, không phải chi tiết vận hành.
Internal model — cơ chế vận hành
Cấu trúc request log
Cloud Armor ghi thông tin vào load balancer request log trong Cloud Logging. Logging tắt mặc định với backend service mới — bạn phải bật (và đặt sampleRate, vì log mọi request ở scale lớn rất tốn kém). Các field chính trong jsonPayload:
enforcedSecurityPolicy— rule thực sự được thực thi, gồm:name— tên policy.priority— priority của rule đã khớp. Field quan trọng nhất để debug: nó cho biết rule nào thực sự thắng theo first-match-wins (file 01). Khi "rule của tôi không có tác dụng", soprioritynày với priority rule bạn mong đợi.configuredAction—ALLOW,DENY,THROTTLE, …outcome—ACCEPT,DENY,REDIRECT,EXEMPT.preconfiguredExprIds— ID của signature WAF đã khớp (dùng để biết signature nào gây match, phục vụ opt-out).rateLimitAction,threatIntelligence,addressGroup— chi tiết theo loại match.
previewSecurityPolicy— cùng cấu trúc, nhưng cho các rule ở preview mode (file 01). Đây là nơi bạn đọc "rule sẽ làm gì nếu enforce" khi test.statusDetails— mô tả người-đọc-được, ví dụdenied_by_security_policy.
Mental model debug: khi điều tra một quyết định Cloud Armor, luôn bắt đầu từ
enforcedSecurityPolicy.priorityvàoutcome. Chúng cho bạn biết rule nào thắng và kết quả — trả lời trực tiếp câu hỏi "vì sao request này bị/không bị chặn" mà không phải suy đoán.
NORMAL vs VERBOSE logging
Đây là phần có rủi ro bảo mật. Cloud Armor có hai mức logging:
NORMAL (mặc định) — ghi các field ở trên: policy name, priority rule khớp, action, outcome, ID signature. Đủ để biết rule nào khớp và kết quả, nhưng không ghi nội dung request cụ thể gây match.
VERBOSE — thêm thông tin về chính field trong request đã gây match cho các preconfigured WAF rule (không áp dụng cho custom rule). Theo tài liệu Google, verbose thêm:
matchedFieldType— loại field gây match (header, cookie, query param, URI…).matchedFieldName— nếu match phần value của một cặp key-value, tên key được ghi vào đây.matchedFieldValue— một prefix tối đa 16 byte của phần field gây match.matchedFieldLength— tổng độ dài của field.
Cơ chế quan trọng và tinh tế: matchedFieldValue bị cắt còn 16 byte đầu. Đây là một dạng giới hạn phơi bày có sẵn — Google không ghi toàn bộ giá trị field, chỉ prefix ngắn để bạn debug. Nhưng 16 byte vẫn đủ để lộ phần đầu của một token, một email, một đoạn payload nhạy cảm.
Vì sao verbose logging là rủi ro dữ liệu nhạy cảm
Bản chất vấn đề: WAF match trên nội dung request thật của user. Khi một request hợp lệ chứa dữ liệu nhạy cảm (token trong query, PII trong body, session trong cookie) tình cờ khớp một signature WAF, verbose logging sẽ ghi prefix 16 byte của chính dữ liệu nhạy cảm đó vào Cloud Logging — nơi có thể được nhiều người truy cập, giữ lâu dài, và nằm ngoài phạm vi kiểm soát dữ liệu của app.
Tài liệu Google nói thẳng: "When you enable verbose logging, there is a risk of accumulating potentially sensitive data in your logs". Khuyến nghị chính thức: chỉ bật verbose logging trong lúc tạo/validate rule hoặc troubleshoot; tắt trong vận hành bình thường.
Đây chính là chủ đề "URL field masking / protecting sensitive data trong logs": Cloud Armor đã giới hạn phơi bày bằng cách cắt còn 16 byte, nhưng trách nhiệm kiểm soát cuối cùng là của bạn qua ba cơ chế:
- Vòng đời verbose logging: bật khi tuning, tắt ngay sau đó. Đây là biện pháp mạnh nhất — dữ liệu không được ghi thì không thể rò rỉ.
- Sampling rate: giảm
sampleRateđể chỉ log một phần request, giảm khối lượng dữ liệu nhạy cảm tích lũy (đánh đổi với độ phủ debug). - Kiểm soát ở Cloud Logging: dùng log exclusion filter để loại field/bản ghi nhạy cảm khỏi sink lưu trữ lâu dài, hoặc kết hợp Cloud DLP / Sensitive Data Protection để phát hiện và redact PII trong log. IAM chặt trên log bucket để giới hạn ai đọc được.
Mental model: verbose logging không phải "bật là an toàn hơn vì có nhiều thông tin". Nó là đánh đổi debug-vs-phơi-bày. Mỗi ngày verbose bật ở production là mỗi ngày dữ liệu nhạy cảm của user có thể tích lũy trong log. Coi nó như một công tắc tạm thời, không phải cấu hình mặc định.
Signed cookies & signed URLs: edge access control cho custom domain
Chuyển sang khía cạnh kiểm soát truy cập ở edge. Khi bạn phục vụ nội dung qua Cloud CDN trên một custom domain, đôi khi bạn cần cấp quyền truy cập giới hạn thời gian cho nội dung riêng tư (video trả phí, file tải về có bản quyền) mà không muốn backend xác thực từng request (tốn kém, và làm mất lợi ích cache của CDN).
Signed URL — ký một URL cụ thể. Client có URL đã ký hợp lệ (chưa hết hạn) thì truy cập được đúng file đó.
Signed cookie — ký quyền truy cập một tập file theo URL prefix. Thay vì ký từng URL (bất khả thi khi có hàng trăm file cho mỗi user, ví dụ các segment của một video HLS), bạn cấp một cookie cho phép truy cập cả prefix https://media.example.com/videos/.
Cấu trúc Cloud-CDN-Cookie (bốn field, phân tách bằng dấu hai chấm, phân biệt hoa thường):
Cloud-CDN-Cookie=URLPrefix=<base64url>:Expires=<unix_ts>:KeyName=<name>:Signature=<sig>URLPrefix— prefix URL (scheme + FQDN + path tùy chọn) mã hóa base64url. Đây là phạm vi quyền.Expires— Unix timestamp (giây) — thời điểm hết hạn.KeyName— tên của signing key đã tạo trên backend service/bucket.Signature— HMAC-SHA-1 của chuỗi policy, mã hóa base64 URL-safe.
Cơ chế validation ở edge:
- Bạn tạo một signing key (128-bit random, base64 URL-safe) trên backend service hoặc backend bucket — tối đa 3 key mỗi backend (để rotate key).
- Ứng dụng của bạn (đã xác thực user) sinh cookie: ghép
URLPrefix:Expires:KeyName, tính HMAC-SHA-1 bằng signing key, gắn vào cookie. - Cloud CDN validate chữ ký ở edge trên mỗi request, trước khi phục vụ nội dung cache hoặc origin. Chữ ký sai hoặc hết hạn → HTTP 403.
Điểm cơ chế quan trọng: validation xảy ra ở edge, nên request không hợp lệ không tới origin — bảo vệ backend và tiết kiệm chi phí. Và response 403 không cacheable, nên chữ ký sai không "đầu độc" cache. Response cho request đã ký và chưa ký được cache riêng biệt.
Constraints, trade-offs & failure modes
Logging tắt mặc định — nhiều team debug Cloud Armor trong bóng tối vì quên bật log cho backend service mới. Bật log (với sampleRate hợp lý) là bước đầu tiên trước khi tune bất cứ thứ gì.
Verbose chỉ cho preconfigured WAF, không cho custom rule — matchedField* chỉ được điền khi match preconfigured WAF signature. Đừng kỳ vọng verbose giải thích vì sao một custom rule khớp; với custom rule, bạn suy từ chính expression + enforcedSecurityPolicy.priority.
Failure mode — verbose bật vĩnh viễn ở production: rủi ro compliance lớn nhất của Cloud Armor logging. Query/cookie/header chứa token, session, PII bị ghi (prefix 16 byte) suốt nhiều tháng, ai có quyền đọc log đều thấy. Khắc phục: coi verbose là công tắc tạm thời; audit định kỳ để đảm bảo nó đã tắt sau các đợt tuning.
16 byte vẫn có thể nhạy cảm — prefix 16 byte đủ lộ phần đầu bearer token, email, hoặc số thẻ (ở một số định dạng). Cắt ngắn giảm rủi ro nhưng không loại bỏ; đừng coi nó là biện pháp redact đủ cho dữ liệu thật sự nhạy cảm.
Signed cookie dùng HMAC-SHA-1 — SHA-1 ở đây dùng trong ngữ cảnh HMAC (không phải chống va chạm hash thuần), vẫn được coi an toàn cho mục đích này, nhưng bảo mật phụ thuộc hoàn toàn vào việc giữ bí mật signing key. Key rò rỉ = bất kỳ ai cũng ký được cookie hợp lệ. Rotate key định kỳ (dùng 3 key slot để rotate không gián đoạn), và không bao giờ đưa signing key xuống client — cookie phải được ký server-side.
Signed cookie/URL không phải authentication — nó là capability token giới hạn thời gian, không xác định ai là user. App vẫn phải xác thực user trước khi cấp cookie. Nó kiểm soát "được truy cập nội dung này tới thời điểm T", không phải "bạn là ai".
Origin phải tự validate độc lập nếu bỏ qua CDN — nếu có đường truy cập origin không qua CDN, origin phải tự từ chối request không ký. Đừng giả định mọi traffic đều đi qua lớp edge validate.
Real-world scenario: tuning WAF an toàn về dữ liệu
Team cần tune WAF SQLi đang gây false positive trên một endpoint nhận JSON có chứa field nhạy cảm (token trong payload). Quy trình đúng theo cơ chế:
- Bật verbose logging tạm thời, với
sampleRatethấp (ví dụ 0.1) để giới hạn khối lượng dữ liệu. - Đặt rule WAF ở preview — đọc
previewSecurityPolicy+matchedFieldName/matchedFieldValueđể biết chính xác field nào và prefix nào gây match. - Từ thông tin đó, thêm field exclusion đúng field (file 02).
- Tắt verbose logging ngay khi xong tuning.
- Rà log sink: đảm bảo không có bản ghi verbose chứa token bị giữ lại lâu dài; nếu có, dùng log exclusion/DLP redact.
Bài học cơ chế: verbose cho bạn đúng thông tin cần để tune (matchedFieldName chỉ thẳng field gây FP), nhưng vòng đời của nó phải ngắn và có kiểm soát dữ liệu, đúng với bản chất con-dao-hai-lưỡi của nó.
Official references
- Verbose logging — NORMAL vs VERBOSE,
matchedField*, cảnh báo dữ liệu nhạy cảm - Per-request logging — cấu trúc
enforcedSecurityPolicy/previewSecurityPolicy, bật logging, sampleRate - Using signed cookies (Cloud CDN) — cấu trúc
Cloud-CDN-Cookie, validation ở edge - Using signed URLs — ký URL đơn lẻ
- Sensitive Data Protection (Cloud DLP) — redact PII trong log