Describe GitHub Advanced Security features and capabilities
This domain tests whether you can map a requirement to the right GitHub Advanced Security (GHAS) capability, and state where that capability is available and how it is billed. Items are usually short scenarios: a plan, a repository visibility and a desired outcome, from which you choose the feature or the licensing consequence.
The capability map
- Code scanning - CodeQL semantic analysis, or SARIF results uploaded from third-party tools; produces per-branch alerts in the Security tab.
- Secret scanning - detects partner and custom patterns in git history; push protection blocks a push containing a supported secret before it lands.
- Dependabot - the dependency graph and GitHub Advisory Database produce alerts; security updates raise fix pull requests; version updates follow
.github/dependabot.yml. - Dependency review - a pull-request gate that fails a PR adding a vulnerable or disallowed-license dependency.
- Supporting features: security overview, repository security advisories and private vulnerability reporting, Copilot Autofix, SBOM export.
Entitlement and billing
Public repositories get code scanning, secret scanning (including push protection) and Dependabot alerts on any plan, including Free. Private and internal repositories need a GHAS licence, which requires GitHub Team or GitHub Enterprise Cloud, and is also sold for GitHub Enterprise Server. GHAS is billed per active committer: a unique account that committed to at least one repository where a GHAS feature is enabled during the billing month. Enabling GHAS on another repository used by the same people adds no seats.
Who can do what
Organization owners enable features and policies; a security manager role can view and manage alerts across the organization without full owner rights; repository admins configure individual repositories. Alert dismissal can be restricted to selected roles.
Worked example
A team on the Free plan wants CodeQL on a private repository and Dependabot alerts on that same repository. Reasoning: both are GHAS features for private repositories, so the organization must move to Team or Enterprise Cloud and license GHAS for the repository; CodeQL additionally needs GitHub Actions enabled, because default setup runs as a workflow and consumes Actions minutes on private repositories.
Traps
- Treating GHAS as per-repository or per-employee; it is per active committer.
- Forgetting that public repositories are already covered on Free.
- Confusing the free dependency graph with licensed Dependabot alerts on private repositories.
- Assuming push protection covers only partner patterns; custom patterns can be push-protected too.
Configure and use CodeQL code scanning
This is the largest domain: configuring CodeQL, choosing the right setup path and query suite, reading alerts, and making results block merges. Expect questions describing a repository's build and asking which configuration is even possible.
Default setup versus advanced setup
- Default setup is switched on in repository settings. GitHub selects the languages, builds compiled languages automatically, and runs on pushes to the default branch, pull requests targeting it, and a weekly schedule. You choose the default or extended query suite. It cannot run custom queries, custom build steps, or a non-Actions CI system.
- Advanced setup commits a workflow (typically
.github/workflows/codeql.yml) callinggithub/codeql-action/init, thenautobuildor your own build commands, thenanalyze. It supports custom query packs, categories for multiple analyses of one repository, and self-hosted runners. - Third-party tools produce SARIF and upload it with
github/codeql-action/upload-sarif, which needs thesecurity-events: writepermission.
Queries, severities and states
Query suites are default, security-extended (more queries, lower precision) and security-and-quality (adds maintainability checks). Alerts carry a rule ID and a security severity from critical to low; state is open, dismissed or fixed, and dismissals record a reason (false positive, won't fix, used in tests). On a pull request the analysis is compared with the base branch, so only new results fail the "Code scanning results" check - and they block merging only when a ruleset enforces merge protection.
Worked example
A Java repository is built with Maven against a private mirror and the team wants the extended suite. Default setup cannot inject a settings.xml or add queries, so use advanced setup: init with languages: java and queries: +security-extended, a manual mvn step, then analyze. Justification: only the workflow path exposes build commands and query selection.
Traps
- Choosing default setup where custom queries or build steps are required.
- Assuming a failing CodeQL check blocks merges without merge protection configured.
- Omitting
security-events: write, so the SARIF upload fails. - Expecting alerts to be branch-independent; they belong to an analysis on a specific ref.
- Assuming
autobuildalways succeeds - complex builds usually need manual steps.
Configure and use secret scanning
Secret scanning items test the difference between detecting a secret that already exists and preventing a new one from being pushed, plus how custom patterns and bypass governance work.
Coverage
For repositories with secret scanning enabled, GitHub scans the full git history of every branch and also scans the titles and descriptions of issues, pull requests, discussions and wikis. Detection comes from three sources: partner patterns for supported providers, non-provider patterns such as generic passwords and private keys, and custom patterns you write as regular expressions. Custom patterns can be defined at organization level (inherited by every repository) or at repository level, and a dry run lets you test a pattern against history before enabling it.
Push protection
Push protection blocks a push containing a supported secret. A member with bypass permission can still push by selecting a reason - used in tests, false positive, or will fix later - and GitHub records a bypassed alert that security overview reports. Bypass permission can be delegated to specific roles, teams or GitHub Apps instead of every writer.
Alert lifecycle and validity
An alert stays open until resolved with a reason: revoked, used in tests, false positive, or won't fix. For some providers GitHub performs a validity check and indicates whether the credential is still active, which helps prioritise live keys. Alerts are exposed through the REST API under /secret-scanning/alerts, the secret_scanning_alert webhook (created, reopened, resolved) and the audit log.
Worked example
An AWS key was committed eight months ago on a feature branch that has since been deleted. Reasoning: deletion changes nothing - an alert already exists and the key remains in history. The correct sequence is to rotate the key in AWS first, then resolve the alert as revoked. Push protection would not have helped retroactively, because it only evaluates incoming pushes.
Traps
- Believing that rewriting history or deleting a branch closes the alert; the credential is still exposed.
- Assuming push protection scans existing history - it does not.
- Thinking a bypassed push produces no alert.
- Granting bypass rights to every contributor when the scenario asks for least privilege.
- Assuming all members can read secret scanning alerts; they are limited to repository admins, organization owners and security managers, whereas code scanning alerts follow repository read access.
Configure and use Dependabot
Dependabot items ask you to distinguish three features that share one data source, configure updates correctly, and predict what happens in CI.
Three distinct features
- Dependabot alerts use the dependency graph and the GitHub Advisory Database. Alerts are raised for the default branch's manifests, and on private repositories they require GHAS.
- Dependabot security updates open a pull request when an alert exists, as soon as the advisory matches - no schedule is involved. They can be grouped into one PR per ecosystem.
- Dependabot version updates follow
.github/dependabot.ymlon the default branch:package-ecosystem,directory,schedule.interval(daily, weekly or monthly - cron is not accepted), plusgroups,ignore,allow,reviewers,assignees,labels,registries,target-branch,versioning-strategyandopen-pull-requests-limit. Setting that limit to 0 switches version updates off.
Dependencies that only appear at build time can be reported through the dependency submission API.
Alert handling
Alerts close automatically once the manifest no longer resolves to a vulnerable version. Dismissal reasons are fix started, tolerable risk, no bandwidth, inaccurate, and not used. Dependabot rules (auto-triage) can auto-dismiss matching alerts.
Worked example
An npm monorepo keeps manifests in /web and /api, uses a private registry, and wants one weekly PR per directory. Reasoning: two updates entries, each with package-ecosystem: npm, its own directory, schedule.interval: weekly, a registries reference to a registry defined in the same file and authenticated with a Dependabot secret, plus a groups block so minor and patch bumps arrive together. One entry cannot cover two directories.
Traps
- Assuming security updates wait for the configured schedule; they do not.
- Committing
dependabot.ymlon a feature branch - only the default branch is read. - Expecting workflows triggered by Dependabot pull requests to see Actions secrets or a write token: those runs get a read-only
GITHUB_TOKENand access Dependabot secrets instead. - Writing a cron expression rather than
daily,weeklyormonthly. - Forgetting that alerts come from default-branch manifests unless dependencies are submitted via the API.
Manage and monitor GitHub Advanced Security for your organization
Management items test scale: how you enable GHAS across many repositories, who can see what, what you are billed for, and how you measure remediation.
Enabling at scale
Rather than toggling features repository by repository, define a security configuration at enterprise level (for example the "GitHub recommended" configuration) that lists code scanning, secret scanning, push protection and Dependabot settings, then apply it to organizations or all repositories and, where required, enforce it so repository admins cannot disable features. Organization security policies still decide whether features apply to all repositories, public repositories only, or are left to opt-in.
Visibility and permissions
The security overview shows coverage and risk across the organization or enterprise, with filters, drill-down links into alerts, a code scanning enablement trend, and CSV export. A security manager can see and manage alerts organization-wide; secret scanning alerts stay restricted to repository admins, organization owners and security managers, while code scanning alerts follow repository read access. Report alert age and mean time to remediation when a scenario asks for metrics.
Billing
GHAS is billed monthly per active committer - a unique account that committed to any repository where GHAS is enabled in that month - not per repository, alert or enabled feature. Enterprise owners review committer usage per organization and repository before expanding the rollout.
Monitoring and integration
Code scanning, secret scanning and Dependabot alerts are exposed through REST and GraphQL endpoints, webhooks and the audit log; audit log streaming forwards security-relevant events to a SIEM. Security campaigns let you group a subset of alerts (for example all critical CodeQL alerts), set a due date and track developer progress toward remediation.
Worked example
An enterprise wants every private repository to have code scanning plus push protection, wants repositories unable to opt out, and needs a monthly remediation metric. Reasoning: create one enforced enterprise security configuration covering those features, then rely on security overview filters or the alerts API to compute mean time to remediation. Per-repository configuration cannot guarantee coverage, and push protection must live in the same configuration to be universal.
Traps
- Assuming the GHAS bill scales with repositories rather than with committers.
- Believing every organization member can see all alerts.
- Rolling out per repository, then being unable to explain incomplete coverage.
- Expecting security overview to configure anything; it reports, while security configurations enforce.
- Setting merge protection in a ruleset but leaving alert dismissal privileges ungoverned.