Skip to main content

Python Bindings for DCAP-QVL

Python bindings for parsing and verifying Intel SGX/TDX DCAP (Data Center Attestation Primitives) quotes. Built on a Rust implementation for use in TEE (Trusted Execution Environment) remote attestation workflows.

Quick Start

# Install from PyPI
pip install dcap-qvl

# Basic usage
python -c "
import dcap_qvl
print('DCAP-QVL Python bindings successfully installed!')
print(f'Available functions: {dcap_qvl.__all__}')
"

Features

  • Parse and inspect SGX/TDX quotes (headers, reports, embedded certificates)
  • Extract PCK certificate extension fields (FMSPC, PPID, CPU SVN, etc.) or look up arbitrary OIDs
  • Verify SGX and TDX quotes against collateral data
  • Handle quote collateral data (serialize/deserialize JSON)
  • Asynchronous collateral fetching from PCCS/PCS with async/await support
  • Pure Rust implementation with Python bindings
  • Cross-platform compatibility (Linux, macOS, Windows)
  • Compatible with Python 3.8+

Installation

pip install dcap-qvl

Using uv

uv add dcap-qvl

Usage

Parsing Quotes

import dcap_qvl

raw = open("quote.bin", "rb").read()
quote = dcap_qvl.parse_quote(raw)

# Quote type
print(quote.quote_type())  # "SGX" or "TDX"
print(quote.fmspc())       # e.g. "B0C06F000000"

# Header fields
hdr = quote.header
print(hdr.version, hdr.tee_type, hdr.attestation_key_type)

# Report body (TdReport10, TdReport15, TdReport15Ex, or SgxEnclaveReport)
report = quote.report
if quote.is_tdx():
    print(report.mr_td.hex())
    print(report.rt_mr0.hex())
else:
    print(report.mr_enclave.hex())
    print(report.mr_signer.hex())
print(report.report_data.hex())

# Embedded PEM certificate chain
pem = quote.cert_chain_pem_bytes()  # bytes or None

PCK Extension Parsing

# From a parsed quote
ext = quote.pck_extension()  # PckExtension or None
if ext:
    print(ext.fmspc.hex())   # 6-byte FMSPC
    print(ext.ppid.hex())    # PPID
    print(ext.cpu_svn.hex()) # CPU SVN
    print(ext.pce_svn)       # PCE SVN (int)
    print(ext.pce_id.hex())  # PCE ID
    print(ext.sgx_type)      # SGX type (int)

# From a PEM certificate chain directly
ext = dcap_qvl.parse_pck_extension_from_pem(pem_bytes)
print(ext.fmspc.hex())

# Look up any OID in the Intel SGX extension (recursive search)
value = ext.get_value("1.2.840.113741.1.13.1.2.17")  # PCESVN
if value is not None:
    print(value.hex())

Basic Quote Verification

import dcap_qvl
import json
import time

# Load quote data (binary)
with open("path/to/quote", "rb") as f:
    quote_data = f.read()

# Load collateral data (JSON)
with open("path/to/collateral.json", "r") as f:
    collateral_json = json.load(f)

# Create collateral object
collateral = dcap_qvl.QuoteCollateralV3.from_json(json.dumps(collateral_json))

# Verify the quote
now = int(time.time())
try:
    result = dcap_qvl.verify(quote_data, collateral, now)
    print(f"Verification successful! Status: {result.status}")
    print(f"Advisory IDs: {result.advisory_ids}")
except ValueError as e:
    print(f"Verification failed: {e}")

Working with Collateral Data

# Create collateral manually
collateral = dcap_qvl.QuoteCollateralV3(
    pck_crl_issuer_chain="...",
    root_ca_crl=b"...",  # bytes
    pck_crl=b"...",      # bytes
    tcb_info_issuer_chain="...",
    tcb_info="...",      # JSON string
    tcb_info_signature=b"...",  # bytes
    qe_identity_issuer_chain="...",
    qe_identity="...",   # JSON string
    qe_identity_signature=b"...",  # bytes
)

# Serialize to JSON
json_str = collateral.to_json()

# Deserialize from JSON
collateral = dcap_qvl.QuoteCollateralV3.from_json(json_str)

API Reference

Async Collateral Functions

All collateral functions are asynchronous and must be awaited. They use the Rust async runtime for optimal performance.

async get_collateral(pccs_url: str, raw_quote: bytes) -> QuoteCollateralV3

Fetch full collateral (PCK cert chain, TCB info, QE identity, CRLs) for a raw DCAP quote from the given PCCS / PCS URL. Handles every supported certification data type (including cert_type 2 / 3 where the PCK cert is retrieved from PCCS via encrypted PPID).

Parameters:

Returns:

  • QuoteCollateralV3: Quote collateral data (with PCK certificate chain attached)

Raises:

  • ValueError: If the quote is invalid, the HTTP client can't be built, or the PCCS / PCS fetch fails

Example:

import asyncio
import dcap_qvl

async def main():
    pccs_url = "https://api.trustedservices.intel.com"
    quote_data = open("quote.bin", "rb").read()
    collateral = await dcap_qvl.get_collateral(pccs_url, quote_data)
    print(f"Got collateral: {len(collateral.tcb_info)} chars")

asyncio.run(main())

async get_collateral_from_pcs(raw_quote: bytes) -> QuoteCollateralV3

Get collateral from Intel's PCS (default).

Parameters:

  • raw_quote: Raw quote data as bytes

Returns:

  • QuoteCollateralV3: Quote collateral data

Raises:

  • ValueError: If quote is invalid or FMSPC cannot be extracted
  • RuntimeError: If network request fails

Example:

import asyncio
import dcap_qvl

async def main():
    quote_data = open("quote.bin", "rb").read()
    collateral = await dcap_qvl.get_collateral_from_pcs(quote_data)
    print(f"Got collateral from Intel PCS")

asyncio.run(main())

async get_collateral_and_verify(raw_quote: bytes, pccs_url: Optional[str] = None) -> VerifiedReport

Get collateral and verify quote in one step.

Parameters:

  • raw_quote: Raw quote data as bytes
  • pccs_url: Optional PCCS URL (uses Intel PCS if None)

Returns:

  • VerifiedReport: Verification results

Raises:

  • ValueError: If quote is invalid or verification fails
  • RuntimeError: If network request fails

Example:

import asyncio
import dcap_qvl

async def main():
    quote_data = open("quote.bin", "rb").read()
    result = await dcap_qvl.get_collateral_and_verify(quote_data)
    print(f"Status: {result.status}")
    print(f"Advisory IDs: {result.advisory_ids}")

asyncio.run(main())

Classes

QuoteCollateralV3

Represents quote collateral data required for verification.

Constructor:

QuoteCollateralV3(
    pck_crl_issuer_chain: str,
    root_ca_crl: bytes,
    pck_crl: bytes,
    tcb_info_issuer_chain: str,
    tcb_info: str,
    tcb_info_signature: bytes,
    qe_identity_issuer_chain: str,
    qe_identity: str,
    qe_identity_signature: bytes,
)

Methods:

  • to_json() -> str: Serialize to JSON string
  • from_json(json_str: str) -> QuoteCollateralV3: Create from JSON string (static method)

Properties:

  • pck_crl_issuer_chain: str
  • root_ca_crl: bytes
  • pck_crl: bytes
  • tcb_info_issuer_chain: str
  • tcb_info: str
  • tcb_info_signature: bytes
  • qe_identity_issuer_chain: str
  • qe_identity: str
  • qe_identity_signature: bytes

VerifiedReport

Contains the results of quote verification.

Properties:

  • status: str: Verification status (e.g., "OK", "SW_HARDENING_NEEDED", "CONFIGURATION_NEEDED", "OUT_OF_DATE", "REVOKED")
  • advisory_ids: List[str]: List of Intel security advisory IDs (e.g., "INTEL-SA-00334")
  • ppid: bytes: Platform PPID parsed from the PCK certificate

Methods:

  • to_json() -> str: Serialize to JSON string

Quote

Represents a parsed SGX or TDX quote. Created via parse_quote() or Quote.parse().

Properties:

  • header: QuoteHeader: Parsed quote header
  • report: Union[TdReport10, TdReport15, TdReport15Ex, SgxEnclaveReport]: Parsed report body

Methods:

  • parse(raw_quote: bytes) -> Quote: Parse from raw bytes (static method)
  • fmspc() -> str: FMSPC as uppercase hex string
  • ca() -> str: Certificate Authority identifier
  • is_sgx() -> bool / is_tdx() -> bool: Check quote type
  • quote_type() -> str: Returns "SGX" or "TDX"
  • cert_chain_pem_bytes() -> Optional[bytes]: Embedded PEM certificate chain
  • pck_extension() -> Optional[PckExtension]: Parse Intel SGX extension from leaf PCK cert

QuoteHeader

Properties:

  • version: int, attestation_key_type: int, tee_type: int
  • qe_svn: int, pce_svn: int
  • qe_vendor_id: bytes (16 bytes), user_data: bytes (20 bytes)

TdReport10 / TdReport15 / TdReport15Ex

TDX TDREPORT structures. TdReport15 extends TdReport10 with tee_tcb_svn2 and mr_service_td. TdReport15Ex (quote v5 body type 4) extends TdReport15 with vmid: int, td_id, dev_info, init_service_td_hash, init_service_td_attributes, init_cpu_svn, init_tee_tcb_svn, init_tee_fmspc, cur_service_td_hash and cur_service_td_attributes.

Properties (TdReport10):

  • tee_tcb_svn: bytes, mr_seam: bytes, mr_signer_seam: bytes, seam_attributes: bytes
  • td_attributes: bytes, xfam: bytes, mr_td: bytes, mr_config_id: bytes
  • mr_owner: bytes, mr_owner_config: bytes
  • rt_mr0: bytes, rt_mr1: bytes, rt_mr2: bytes, rt_mr3: bytes
  • report_data: bytes

SgxEnclaveReport

Properties:

  • cpu_svn: bytes, attributes: bytes
  • mr_enclave: bytes, mr_signer: bytes
  • report_data: bytes

PckExtension

Parsed values from the Intel SGX extension in the PCK leaf certificate.

Properties:

  • ppid: bytes, cpu_svn: bytes, pce_svn: int, pce_id: bytes
  • fmspc: bytes (6 bytes), sgx_type: int
  • platform_instance_id: Optional[bytes]

Methods:

  • get_value(oid: str) -> Optional[bytes]: Look up any OID in the Intel SGX extension by dotted-decimal string. Returns raw DER value bytes, or None if not found.

Functions

parse_quote(raw_quote: bytes) -> Quote

Parse a raw SGX or TDX quote from bytes.

parse_pck_extension_from_pem(pem_bytes: bytes) -> PckExtension

Parse the Intel SGX extension from a PEM-encoded certificate chain (uses the first/leaf certificate).

verify(raw_quote: bytes, collateral: QuoteCollateralV3, now_secs: int) -> VerifiedReport

Verify a quote with the provided collateral data.

Parameters:

  • raw_quote: Raw quote data as bytes
  • collateral: Quote collateral data
  • now_secs: Current timestamp in seconds since Unix epoch

Returns:

  • VerifiedReport: Verification results

Raises:

  • ValueError: If verification fails

verify_with_root_ca(raw_quote: bytes, collateral: QuoteCollateralV3, root_ca_der: bytes, now_secs: int) -> VerifiedReport

Verify a quote with a custom root CA certificate (DER format) instead of the built-in Intel root CA.

Development

Building from Source

If you want to build from source or contribute to development:

# Clone the repository
git clone https://github.com/Phala-Network/dcap-qvl.git
cd dcap-qvl/python-bindings

# Install development dependencies (including maturin)
uv sync

# Build and install the Python extension in development mode
uv run maturin develop --features python

# Run tests
uv run pytest tests/ -v

Note: maturin is only required for building from source. Regular users installing from PyPI don't need maturin.

Running Examples

After installing the package, you can run the examples:

# Download the examples from the repository
git clone https://github.com/Phala-Network/dcap-qvl.git
cd dcap-qvl/python-bindings

# Basic functionality test
python examples/basic_test.py

# Full example (requires sample data files)
python examples/python_example.py

Or if you're using uv for development:

# Basic functionality test
uv run python examples/basic_test.py

# Full example (requires sample data files)
uv run python examples/python_example.py

Testing Across Python Versions

The project includes comprehensive testing across all supported Python versions:

# Quick test across all Python versions
make test_python_versions

# Test current Python version only
make test_python

See PYTHON_TESTING.md for detailed information about Python version compatibility testing.

Requirements

For regular usage (installing from PyPI):

  • Python 3.8+

For development (building from source):

  • Python 3.8+
  • Rust toolchain (rustc, cargo) 1.83+
  • maturin (automatically installed with uv sync)

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Metadata

Release files for dcap-qvl 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dcap-qvl 0.7.1
File Size Uploaded Provenance Actions
dcap_qvl-0.7.1.tar.gz 306.1 kB With provenance Details for dcap_qvl-0.7.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for dcap-qvl 0.7.1
File Actions
dcap_qvl-0.7.1-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details for dcap_qvl-0.7.1-cp38-abi3-win_amd64.whl
dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_x86_64.whl CPython 3.8 abi3 Linux musl 1.1+ x86-64 Details for dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_x86_64.whl
dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_aarch64.whl CPython 3.8 abi3 Linux musl 1.1+ ARM64 Details for dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_aarch64.whl
dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details for dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details for dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
dcap_qvl-0.7.1-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details for dcap_qvl-0.7.1-cp38-abi3-macosx_11_0_arm64.whl
dcap_qvl-0.7.1-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details for dcap_qvl-0.7.1-cp38-abi3-macosx_10_12_x86_64.whl

Total release size: 17.9 MB

Release files / dcap_qvl-0.7.1.tar.gz

Download URL dcap_qvl-0.7.1.tar.gz
Size 306.1 kB
Tags Source
SHA-256 checksum
How to use checksums
d74d3cf272b77b0c756b4f328f833b40506d151720aee0db480099ecc9c80477
BLAKE2b-256 checksum
How to use checksums
351d9c635bc72b412cc4376e076b2e990c1fbf6d853b6f454409d3c203c6b33e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-win_amd64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-win_amd64.whl
Size 2.1 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
02aa45f2ff65221453e872e314ffc35bfb035e199d5d1f4aa890d43bb4f33a35
BLAKE2b-256 checksum
How to use checksums
2f4c3289901019a887cf94fcd894228db2d5f2c41b44b58d367d441807aac992
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_x86_64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_x86_64.whl
Size 2.7 MB
Tags CPython 3.8 Linux musl 1.1+ x86-64 abi3
SHA-256 checksum
How to use checksums
ab1bfa18ce9e0a9ba7554ccbb1bfb4eccdd420d6769171406e386e32004e2062
BLAKE2b-256 checksum
How to use checksums
68b2799bef3fc8c2fe5e3084cebbd576bf0d32f01384e8b622fe7ef776f28226
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_aarch64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-musllinux_1_1_aarch64.whl
Size 2.6 MB
Tags CPython 3.8 Linux musl 1.1+ ARM64 abi3
SHA-256 checksum
How to use checksums
0dfb73b1cc92c00c29987b49912a0ed635fc67f4f6219db04832746ff2dddfef
BLAKE2b-256 checksum
How to use checksums
3923ccd89990f75c8b9b8d24cd7ef1f4646b5e0336cb38bab54b852937308772
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.7 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
0411ae71234f95d779e424a0e21e93f52098e9b95f09f18ea200d495a4c9138e
BLAKE2b-256 checksum
How to use checksums
f43a0e6d327b6c1965ddd61162faedc36f2991a29f20a693643eb6abea5d6c8f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 2.6 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
582b1afb1cce7981669d30480dea1528752e8f5de92b23236a08e6342fe5b6bc
BLAKE2b-256 checksum
How to use checksums
f832a62e54dd616d26a1d09bdf5d826b543b392b53b972dbc9ccc1479d0c6edc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-macosx_11_0_arm64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-macosx_11_0_arm64.whl
Size 2.3 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
092d4d7b8e790b36f571deb711c8301c32219ba496d15f240fb5bbd35a2d01ea
BLAKE2b-256 checksum
How to use checksums
7a2366d26adfc1b76827f92535cb865a91c92f42ec47d75e239a34eab2013910
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Release files / dcap_qvl-0.7.1-cp38-abi3-macosx_10_12_x86_64.whl

Download URL dcap_qvl-0.7.1-cp38-abi3-macosx_10_12_x86_64.whl
Size 2.4 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
bc1b04084873508531a2c0c80ab687a8e0ea4daa544c3d41c9610c5170c8ef7c
BLAKE2b-256 checksum
How to use checksums
45f7210616a73c99b359064a1df6ca30a22602ea61598114e7f87b95d5db90ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

Security for dcap-qvl 0.7.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for dcap_qvl-0.7.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page