EmitCI is built with a security-first mindset. Here is exactly what we access, why, and how we protect it.
TLS 1.2+ enforced via Cloudflare with HSTS (max-age 1 year). Credentials encrypted at rest with AES-256-GCM. Database storage encrypted at the infrastructure level.
For GitHub Actions, the EmitCI GitHub App requests only four permissions — all read-only except Commit statuses (for budget enforcement). No secrets, no PRs, no write access to code. For Bitbucket, Azure DevOps, CircleCI, and Jenkins, credentials (App Passwords, PATs, API tokens) are encrypted with AES-256-GCM and used only for read-only API polling. EmitCI never modifies pipelines, commits, or CI configurations on any platform.
Every significant action — role changes, webhook events, report generation, account deletion — is logged with actor, IP, and timestamp. Full export for Enterprise.
Found a vulnerability? Email [email protected]. We acknowledge within 24 hours and patch critical issues within 7 days. No legal action against good-faith researchers.
This table applies to GitHub Actions users. This is the complete permission list — every permission not shown here is absent. GitHub presents a consent screen before anything is granted. For GitLab, Bitbucket, Azure DevOps, CircleCI, and Jenkins, see the credential security section below.
| Permission | Access | Why |
|---|---|---|
| Actions | Read-only | Workflow run status, job names, step names, runner labels, and durations. The only data EmitCI analyses. |
| Metadata | Read-only | Repository names and visibility. Required by GitHub for all Apps — cannot be removed. No repository contents included. |
| Commit statuses | Write | Posts a carbon-budget status check on commits so you can optionally block merges when a repo's monthly CO₂ budget is exceeded. Opt-in via your branch protection rules. |
| Contents (source code) | Read-only | Workflow YAML files (.github/workflows/*.yml) and Dockerfiles are read to generate CI optimisation recommendations (e.g. missing cache layers, oversized base images). Application source code is not accessed or stored. |
| Secrets & variables | None | — |
| Environments | None | — |
| Pull requests | None | — |
| Issues | None | — |
| Deployments | None | — |
| Administration | None | — |
| Members & teams | None | — |
| Webhooks | None | — |
For GitHub Actions users, installing EmitCI involves two distinct GitHub authorisations. Security teams are sometimes alarmed by the OAuth screen, which looks broader than it is. Here is exactly what each step does.
GitLab users go through a single GitLab OAuth flow. Google, email, Bitbucket, Azure DevOps, CircleCI, and Jenkins users sign in without any GitHub interaction — credentials are entered directly in the onboarding form and stored encrypted.
The org admin installs the EmitCI GitHub App. GitHub presents a permission consent screen showing exactly what is requested. The admin selects which repositories to grant access to — they can limit it to specific repos rather than the whole organisation.
When a user signs in, we use GitHub OAuth to confirm their identity and verify they are a member of an org that has the app installed. The scopes requested are read:org and repo:
read:orgVerifies that the person logging in is a member of an org that has EmitCI installed, so we can show them the correct dashboard. No org settings, teams, or member lists are stored.
repoRequired by GitHub to confirm which private repositories exist inside an org. EmitCI reads only repository names to display them in the dashboard — never contents, diffs, commits, or code.
These scopes are never used to read code, write to repos, or access anything beyond confirming org membership.
For Bitbucket Pipelines, Azure DevOps, CircleCI, and Jenkins, EmitCI stores credentials you provide during onboarding (App Passwords, Personal Access Tokens, or API tokens). Here is exactly how they are handled.
Encrypted at rest
Credentials are encrypted with AES-256-GCM before being written to the database. The plaintext is never stored.
Never returned via API
Credential read endpoints return only metadata (provider, org slug, last polled timestamp). The encrypted token is never sent to the browser.
Read-only polling only
Credentials are used exclusively to call list-pipelines and list-steps API endpoints. EmitCI never creates, modifies, or deletes anything on your CI platform.
Revocable at any time
Delete credentials from Settings → Integrations. Polling stops immediately and the encrypted token is permanently deleted from the database.
All data is stored and processed in the United States (Fly.io, Washington DC / iad). Data does not leave US infrastructure. DPAs available for Enterprise customers.
Only org members granted access via EmitCI RBAC. EmitCI staff access production only for incident response, with full audit logging. We never sell or share your data.
SOC 2 Type II
PlannedOn our roadmap. Enterprise customers can request our security questionnaire in the meantime.
GDPR
CompliantOne-click account deletion, right to erasure (Article 17), data processing agreements available on request.
Security questionnaires
AvailableEmail [email protected] with your questionnaire. We respond within 2 business days.
Found a security vulnerability? Please report it responsibly. We do not pursue legal action against researchers who follow responsible disclosure guidelines.
[email protected] →Acknowledged within 24 hours · Critical issues patched within 7 days