Back to Checks
Repository is archived or active within the configured inactivity threshold
repository_inactive_not_archived
Service: repositorySeverity: medium
OfficialBuilt-inVerified
Categories:software-supply-chain
Resource Type:NotDefined
GitHub repository that remains unarchived and show no activity beyond a configured inactivity window (e.g., 180 days) are identified. The evaluation considers the most recent repository activity to surface long-idle codebases that are still unarchived.
Risk
Unarchived, long-inactive repos expand attack surface. Stale code and dependencies can hide unpatched flaws; writable state enables integrity compromise via malicious commits or workflow abuse; exposed secrets threaten confidentiality. Attackers can leverage them for lateral movement and supply-chain tampering.
Run this check with Prowler
Run in Prowler CloudRun
prowler github --checks repository_inactive_not_archivedRecommendation
Adopt lifecycle management:
- Archive or delete repos no longer needed
- If retained, update dependencies, rotate secrets, disable unused workflows, and restrict writes under least privilege
- Define an inactivity policy (e.g.,
180days) with periodic reviews to prevent dormant, writable codebases
Remediation
CLI
gh repo archive <OWNER>/<REPO> --yesTerraform
resource "github_repository" "repo" {
name = "<example_resource_name>"
archived = true # Critical: archives the repository so inactive repos pass the check
}Other
1Open the repository on GitHub
2Click Settings
3Scroll to Danger Zone
4Click Archive this repository
5Type the repository name and confirm by clicking I understand the consequences, archive this repository
Check Code
from datetime import datetime, timezone
from typing import List
from prowler.lib.check.models import Check, CheckReportGithub
from prowler.providers.github.services.repository.repository_client import (
repository_client,
)
class repository_inactive_not_archived(Check):
"""Check if unarchived repositories have been inactive for more than 6 months."""
def execute(self) -> List[CheckReportGithub]:
findings = []
now = datetime.now(timezone.utc)
days_threshold = repository_client.audit_config.get(
"inactive_not_archived_days_threshold", 180
)
for repo in repository_client.repositories.values():
report = CheckReportGithub(metadata=self.metadata(), resource=repo)
if repo.archived:
report.status = "PASS"
report.status_extended = f"Repository {repo.name} is properly archived."
findings.append(report)
continue
latest_activity = repo.pushed_at
days_inactive = (now - latest_activity).days
if days_inactive >= days_threshold:
report.status = "FAIL"
report.status_extended = f"Repository {repo.name} has been inactive for {days_inactive} days and is not archived (threshold: {days_threshold} days)."
else:
report.status = "PASS"
report.status_extended = f"Repository {repo.name} has been active within the last {days_threshold} days ({days_inactive} days ago)."
findings.append(report)
return findings