Back to Checks
github

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 Cloud
Run
prowler github --checks repository_inactive_not_archived

Recommendation

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., 180 days) with periodic reviews to prevent dormant, writable codebases

Remediation

CLI

gh repo archive <OWNER>/<REPO> --yes

Terraform

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