Back to Checks
Organization has maximum validity period of 8 hours or less for Admin API Service Account secrets
organizations_service_account_secrets_expiration
Service: organizationsSeverity: high
OfficialBuilt-inVerified
Categories:secrets
Resource Type:NotDefined
MongoDB Atlas organization setting maxServiceAccountSecretValidityInHours caps the lifetime of new Admin API service account secrets. Evaluation focuses on whether a limit is configured and whether it is at or below the defined policy threshold (default 8 hours).
Risk
Overlong or unset lifetimes for Admin API service account secrets expand the attack window. If leaked, an adversary can maintain API access to:
- Exfiltrate data (confidentiality)
- Alter org or project configs (integrity)
- Disable services or change access controls (availability)
Run this check with Prowler
Run in Prowler CloudRun
prowler mongodbatlas --checks organizations_service_account_secrets_expirationRecommendation
Set a strict cap via maxServiceAccountSecretValidityInHours to 8 hours or less. Apply least privilege to service accounts, automate secret rotation/revocation, and monitor usage. Store secrets in a secure vault and limit where they can be used e.g., network allowlisting as part of defense in depth.
Remediation
CLI
curl --user "<PUBLIC_KEY>:<PRIVATE_KEY>" --digest -H "Content-Type: application/json" -X PATCH "https://cloud.mongodb.com/api/atlas/v2/orgs/<ORG_ID>/settings" --data '{"maxServiceAccountSecretValidityInHours":8}'Terraform
resource "mongodbatlas_organization_settings" "<example_resource_name>" {
org_id = "<example_resource_id>"
max_service_account_secret_validity_in_hours = 8 # Critical: enforce <= 8 hours for Admin API Service Account secrets
}Other
1In the MongoDB Atlas UI, select your organization
2Go to Organization > Settings
3Set "Maximum validity for Admin API Service Account secrets" to 8 hours (or less)
4Click Save
Check Code
from typing import List
from prowler.lib.check.models import Check, CheckReportMongoDBAtlas
from prowler.providers.mongodbatlas.services.organizations.organizations_client import (
organizations_client,
)
class organizations_service_account_secrets_expiration(Check):
"""Check if organization has maximum period expiration for Admin API Service Account Secrets
This class verifies that MongoDB Atlas organizations have a maximum period
before expiry for new Atlas Admin API Service Account secrets.
"""
def execute(self) -> List[CheckReportMongoDBAtlas]:
"""Execute the MongoDB Atlas organization service account secrets expiration check
Iterates over all organizations and checks if they have a maximum period
expiration for Admin API Service Account secrets set to 8 hours or less.
Returns:
List[CheckReportMongoDBAtlas]: A list of reports for each organization
"""
findings = []
# Get configurable threshold from audit config, default to 8 hours
max_hours_threshold = organizations_client.audit_config.get(
"max_service_account_secret_validity_hours", 8
)
for organization in organizations_client.organizations.values():
report = CheckReportMongoDBAtlas(
metadata=self.metadata(), resource=organization
)
if (
organization.settings.max_service_account_secret_validity_in_hours
is None
):
report.status = "FAIL"
report.status_extended = (
f"Organization {organization.name} does not have a maximum period "
f"expiration configured for Admin API Service Account secrets."
)
elif (
organization.settings.max_service_account_secret_validity_in_hours
<= max_hours_threshold
):
report.status = "PASS"
report.status_extended = (
f"Organization {organization.name} has a maximum period expiration "
f"of {organization.settings.max_service_account_secret_validity_in_hours} hours for Admin API Service Account secrets, "
f"which is within the recommended threshold of {max_hours_threshold} hours."
)
else:
report.status = "FAIL"
report.status_extended = (
f"Organization {organization.name} has a maximum period expiration "
f"of {organization.settings.max_service_account_secret_validity_in_hours} hours for Admin API Service Account secrets, "
f"which exceeds the recommended threshold of {max_hours_threshold} hours."
)
findings.append(report)
return findings