Yes. A GitHub Actions workflow on a schedule can open an issue for every recurring control, such as a monthly access review, with a checklist and an owner assigned. It reminds people and leaves a dated record. Design around three limits: schedules run in UTC, can be delayed, and may be disabled in quiet public repositories.
What GitHub documents
GitHub's documentation says to use POSIX cron syntax for scheduled workflows and that the shortest interval is once every 5 minutes. Scheduled workflows run on the latest commit on the default branch, and the schedule event can be delayed during periods of high load. By default they run in UTC. In a public repository, scheduled workflows are automatically disabled when there has been no repository activity for 60 days.
Why this suits control calendars
A control calendar in a spreadsheet depends on someone looking at it. An issue appears in the owner's queue, can be assigned, commented on and closed. The closed issue, with its timestamps and comments, is the evidence.
A minimal design
- Keep a
controlsrepository, private, with one issue template per recurring control. - Write a workflow with a cron schedule for each frequency, for example the first weekday of each month.
- The workflow creates an issue from the template, assigns the control owner and adds a label such as
controland the frequency. - The owner completes the checklist, attaches or links evidence and closes the issue.
- A second scheduled job lists open control issues older than their due date and posts to chat.
- Monthly, export closed issues to the evidence store.
A sketch of the schedule block:
on:
schedule:
- cron: "0 9 1 * *"
workflow_dispatch:
The workflow_dispatch line lets you run it by hand, which helps testing and catch-up.
Limits to plan for
| Limit | What it means | What to do |
|---|---|---|
| UTC by default | A 9 am job is 9 am UTC | State times in UTC in the narrative |
| Possible delay | Runs may start late at peak times | Do not depend on exact minutes, use due dates a day or more out |
| Default branch only | Changes on other branches do not affect it | Protect the default branch of this repo |
| 60 day disable in quiet public repos | Job can stop silently | Use a private repo, or add a heartbeat check |
| Failed workflows | No issue is created | Alert on workflow failure, and compare issue counts to the calendar |
The last row is important. A control that fails to create its reminder fails silently. Add a monthly check that every expected issue exists.
Pitfalls
- Treating a closed issue as proof without evidence attached. Require a link in the closing comment.
- Letting anyone edit closed issues. Restrict permissions and review changes.
- Putting secrets in issue text.
Quick check
Does the schedule run at exactly the stated minute?
Not guaranteed. GitHub says it can be delayed during high load, so allow slack.
What if the repository is quiet?
In public repositories, scheduled workflows can be disabled after 60 days without activity. Use a private repo or make a regular commit.
Safeguard compliance and evidence automation can also collect recurring evidence for you. Try a free scan.
Sources
Last reviewed: 19 October 2026.