RoastMyOpsec

Vulnerabilities

CircleCI config vs GitHub Workflows on Production Origins

June 29, 2022

CircleCI config vs GitHub workflows on a production origin is two CI description trees sitting where only the website should live. Workflow YAML can name jobs, third-party actions, environments, and sometimes plaintext secrets someone pasted 'for a minute.' Serving that next to index.html is the same class of miss as /package.json. RoastMyOpsec may not fetch CircleCI or GitHub workflow files today. Still deny those names at the CDN. Do not list CI paths in robots.txt — that is a map, not a lock.

The practical difference

CircleCI typically lives as config YAML in a CI folder. GitHub Actions lives as workflow YAML under .github. Different vendors, same leak: the production document root is not your pipeline.

Hardening workflows — least privilege, no long-lived tokens in YAML — belongs in the private repo. Publishing the YAML does not make it safer. It donates the pipeline map.

How to choose based on what you shipped

Fail CI (ironically) if workflow YAML appears in a static marketing artifact. Deny those tree prefixes at the CDN without advertising them in robots.txt. If a public file may have held a token, rotate it. Keep pipeline files in git, not in dist/.

OptionWhen it winsWatch-outTakeaway
GitHub workflow YAML in gitPrivate repo Actions you controlDo not copy .github into the bucketNever as a CDN object
CircleCI config in gitPrivate CircleCI projectsOrbs and contexts are still a map if publicSame class of miss on the origin
Either YAML on the originNeverPipeline plus possible secretsDeny the names at the edge
/package.json on the originAlmost neverInventory cousinRoast signatures this path today

When each CI file wins (off the public origin)

GitHub workflow files win in a private repository with least-privilege tokens. CircleCI config wins in that same private arrangement for CircleCI users. Neither wins as a downloadable object on the brochure host.

A public GitHub repo already publishes workflows by design. That is a product choice. Mirroring those files onto a marketing CDN is still a leftover sync, not a requirement.

Common mistakes

The first mistake is rsyncing the repo including .github or .circleci because the static site generator lived in the same tree.

The second mistake is pasting a cloud token into YAML 'temporarily' and then shipping that file to the origin.

The third mistake is Disallowing CI folders in robots.txt instead of denying them at the CDN.

What a URL roast can prove

The roast signatures /package.json, /.env, and /.git/HEAD among a short leftover list. CircleCI config and GitHub workflow paths are not scored today. Still deny them. Bounded GETs, no workflow dispatch, no secret use. Confirm the bucket.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Is public CI YAML a vulnerability?
On a marketing origin it is an information leak and, if it held secrets, a credential incident. Remove it and deny the names at the edge.
Does RoastMyOpsec fetch CircleCI or GitHub workflow files?
Not as scored paths today. It does probe other well-known leftovers. Deny CI filenames at the CDN anyway. Same class of miss as /package.json.
Our GitHub repo is public. Why deny workflows on the CDN?
The repo is one channel. The CDN is another leftover sync that also tends to drag .env and lockfiles with it. Deny the names on the origin either way.

Sources

Related guides