Compliance Dashboards¶
Compliance teams need to see cloud configuration data — S3 bucket policies, encryption settings, security group rules, IAM configurations. Traditionally, this means requesting screenshots from engineering or waiting for an export that is stale before it arrives.
A LightPane compliance dashboard shows live data, scoped to exactly the services and accounts the compliance team needs.
Scope an access key for compliance¶
Create an embed key that grants access only to compliance-relevant services:
- Go to Access Keys in your LightPane account
- Click Create New Key
-
Set:
- Label: "Compliance dashboard — production"
- Type:
embed - Cloud account: Select the production account
- Services: Select specific services:
Service What it shows s3Bucket configurations, encryption, public access settings kms_keysKMS key configurations and rotation status security_groupsInbound and outbound rules iam_usersIAM users and access key ages iam_rolesIAM roles and trust policies rds_instancesEncryption, backup, and Multi-AZ configuration cloudtrailRecent API activity -
Set constraints:
allowed_origins: the domain where the dashboard is hostedrate_limit_rpm:30
- Click Create and copy the token
This key can only discover the selected services in the selected account. Even if the token is exposed, it cannot access other services or accounts.
Build the dashboard page¶
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Compliance Dashboard — Production</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<link rel="stylesheet"
href="https://cdn.lightpane.cloud/sdk/v1/clouds-and-light.css">
</head>
<body>
<div class="container mt-4">
<h1>Production Compliance Dashboard</h1>
<p class="text-muted">
Live data from AWS account 123456789012.
Last loaded: <span id="load-time"></span>
</p>
<script>
var serviceDiscoveryConfig = {
accessKey: 'csl_em_YOUR_ACCESS_KEY_HERE'
};
var serviceDiscoveryRequests = serviceDiscoveryRequests || [];
serviceDiscoveryRequests.push({
service: 's3',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
attributes: ['bucket_name', 'creation_date', 'region',
'encryption', 'public_access_block', 'versioning']
});
serviceDiscoveryRequests.push({
service: 'kms_keys',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
attributes: ['key_id', 'description', 'key_state',
'rotation_enabled', 'creation_date']
});
serviceDiscoveryRequests.push({
service: 'security_groups',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
attributes: ['group_name', 'group_id', 'vpc_id', 'description']
});
serviceDiscoveryRequests.push({
service: 'iam_users',
provider: 'aws',
region: 'us-east-1',
source: 'live',
attributes: ['user_name', 'create_date', 'password_last_used',
'access_key_age']
});
serviceDiscoveryRequests.push({
service: 'rds_instances',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
attributes: ['name', 'engine', 'storage_encrypted',
'multi_az', 'backup_retention_period']
});
serviceDiscoveryRequests.push({
service: 'cloudtrail',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
attributes: ['event_time', 'event_name', 'username',
'resource_type', 'resource_name']
});
document.getElementById('load-time').textContent = new Date().toLocaleString();
</script>
<h2>S3 Bucket Configuration</h2>
<div data-sd-service="s3" data-sd-source="live"></div>
<h2>KMS Key Status</h2>
<div data-sd-service="kms_keys" data-sd-source="live"></div>
<h2>Security Groups</h2>
<div data-sd-service="security_groups" data-sd-source="live"></div>
<h2>IAM Users</h2>
<div data-sd-service="iam_users" data-sd-source="live"></div>
<h2>RDS Encryption & Backup</h2>
<div data-sd-service="rds_instances" data-sd-source="live"></div>
<h2>Recent API Activity</h2>
<div data-sd-service="cloudtrail" data-sd-source="live"></div>
</div>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-core.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-fetch.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-render.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-format.js"></script>
<script src="https://cdn.lightpane.cloud/sdk/v1/sd-boot.js"></script>
</body>
</html>
Multiple accounts on one dashboard¶
If the compliance team needs to see data from multiple AWS accounts, create one access key per account and use separate config sections. Or create a single key that includes multiple cloud account bindings.
// Key with access to both production and staging
var serviceDiscoveryConfig = {
accessKey: 'csl_em_KEY_WITH_MULTIPLE_ACCOUNTS'
};
serviceDiscoveryRequests.push({
service: 's3',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
account: '111111111111' // production
});
serviceDiscoveryRequests.push({
service: 's3',
provider: 'aws',
region: 'eu-west-2',
source: 'live',
account: '222222222222' // staging
});
Embedding in compliance documents¶
For compliance reports or audit evidence, embed panes in internal web-based documents. The pane shows live data at the time the page is loaded.
To capture a point-in-time snapshot:
- Load the compliance dashboard page
- Print to PDF (++ctrl+p++ or ++cmd+p++)
- The PDF captures the rendered tables with current data and a timestamp
For automated snapshots, use the Python guide to call the API and generate reports on a schedule.
Access key recommendations for compliance¶
| Setting | Recommendation |
|---|---|
| Type | embed for web dashboards, api_key for automated reports |
| Services | Scope to compliance-relevant services only |
| Cloud account | Scope to the specific account being audited |
allowed_origins |
Set to the internal domain hosting the dashboard |
| Expiry | Align with audit cycle (e.g. 90 days, renew at each audit) |
Separate keys per compliance domain
Create separate access keys for different compliance concerns. A data protection dashboard might need S3 and KMS. A network security dashboard might need security groups and VPCs. Separate keys mean separate scopes, reducing the blast radius if a token is compromised.
Use the API for automated compliance checks¶
Combine the Python guide with compliance-specific logic:
import os
import requests
API_URL = "https://api.lightpane.cloud/services/discover"
TOKEN = os.environ["LIGHTPANE_API_KEY"]
response = requests.post(API_URL, json={
"services": [
{"service": "s3", "provider": "aws", "region": "eu-west-2",
"attributes": ["bucket_name", "encryption", "public_access_block",
"versioning"]}
]
}, headers={
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"
})
response.raise_for_status()
data = response.json()
issues = []
for result in data.get("results", []):
for bucket in result.get("rows", []):
if not bucket.get("encryption"):
issues.append(f"S3 bucket {bucket['bucket_name']} has no encryption")
if not bucket.get("versioning"):
issues.append(f"S3 bucket {bucket['bucket_name']} has versioning disabled")
if issues:
print(f"COMPLIANCE ISSUES FOUND ({len(issues)}):")
for issue in issues:
print(f" - {issue}")
else:
print("All S3 buckets pass compliance checks.")