> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Integrations Private Repository

> Guide to configuring Backstage to access and import catalog files from private GitHub repositories using a personal access token and integrations in app-config.yaml

This lesson shows how to configure Backstage so it can fetch catalog entity files from a private GitHub repository. By default Backstage reads public repositories without authentication, but private repositories require a GitHub integration and an access token (Personal Access Token — PAT).

What you'll see here:

* Turn a repository private and reproduce the import error.
* Generate a GitHub PAT with minimal scopes.
* Configure Backstage to use the token and allow access to `raw.githubusercontent.com`.
* Restart Backstage and successfully import the entity.

We begin with a repository that was public and has been changed to private in the GitHub repository settings:

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/cTFshlV6LNi9HF-G/images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/github-settings-backstage-auth-service-main.jpg?fit=max&auto=format&n=cTFshlV6LNi9HF-G&q=85&s=1cd4a66f3989a160f8625ed20be0b769" alt="A screenshot of a GitHub repository's Settings → General page for &#x22;backstage-auth-service,&#x22; showing the repository name, options to rename, and the default branch set to &#x22;main.&#x22; The left sidebar lists settings sections like Collaborators, Branches, Actions, Webhooks, and Security." width="1920" height="1080" data-path="images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/github-settings-backstage-auth-service-main.jpg" />
</Frame>

When you attempt to register the existing component by pointing Backstage at the repository `catalog-info.yaml`, the backend will return a 404 because it cannot read the `raw.githubusercontent.com` URL without authentication. Example error returned by the Backstage backend:

```json theme={null}
{
  "error": {
    "name": "InputError",
    "message": "NotFoundError: Unable to read url, NotFoundError: Request failed for https://raw.githubusercontent.com/Sanjeev-Thiyagarajan/backstage-auth-service/main/catalog-info.yaml, 404 Not Found",
    "stack": "InputError: NotFoundError: Unable to read url, NotFoundError: Request failed for https://raw.githubusercontent.com/Sanjeev-Thiyagarajan/backstage-auth-service/main/catalog-info.yaml, 404 Not Found\n    at DefaultLocationService.processEntities (/root/demo/backstage/node_modules/@backstage/plugin-catalog-backend/src/service/DefaultLocationService.ts:110:15)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at DefaultLocationService.tryRunCreateLocation (/root/demo/backstage/node_modules/@backstage/plugin-catalog-backend/src/service/DefaultLocationService.ts:148:32)\n    at <anonymous> (/root/demo/backstage/node_modules/@backstage/plugin-catalog-backend/src/service/createRouter.ts:322:24)"
  },
  "request": {
    "method": "POST",
    "url": "/locations?dryRun=true"
  },
  "response": {
    "statusCode": 400
  }
}
```

The 404 indicates Backstage was blocked from accessing the raw URL — because the repository is private. To allow Backstage to fetch files from private repositories you must configure the GitHub integration and provide a token that permits reading private repo contents.

The entity file we attempted to import (`catalog-info.yaml`) looks like this:

```yaml theme={null}
apiVersion: backstage.io/v1beta1
kind: Component
metadata:
  name: auth-service
  description: authentication service
  tags:
    - javascript
  links:
    - url: https://google.com
      title: Admin Dashboard
      icon: dashboard
      type: admin-dashboard
spec:
  type: service
  lifecycle: production
  owner: guests
  providesApis:
    - auth-api
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
  name: auth-api
  description: Verify user authentication status
spec:
  type: openapi
  lifecycle: production
  owner: guests
  apiProvidedBy: auth-service
```

## Backstage configuration required

Backstage uses an `integrations` section in `app-config.yaml` to authorize GitHub requests. At minimum you must:

* Allow reading `raw.githubusercontent.com` in the `reading.allow` list.
* Add a `github` integration entry and provide a token (via environment variable is recommended).

Example `app-config.yaml` snippet:

```yaml theme={null}
reading:
  allow:
    - host: 'raw.githubusercontent.com'

integrations:
  github:
    - host: github.com
      # This is a Personal Access Token (PAT) from GitHub.
      # Prefer reading this from an environment variable rather than hardcoding.
      token: ${GITHUB_TOKEN}

# Example for GitHub Enterprise:
# - host: ghe.example.net
#   apiBaseUrl: https://ghe.example.net/api/v3
#   rawBaseUrl: https://ghe.example.net/raw
#   token: ${GHE_TOKEN}
```

Table — key configuration items

| Item                          | Purpose                                     | Example / Note                         |
| ----------------------------- | ------------------------------------------- | -------------------------------------- |
| `reading.allow`               | Permit Backstage to fetch raw URLs          | `- host: 'raw.githubusercontent.com'`  |
| `integrations.github[].host`  | GitHub host for the integration             | `github.com`                           |
| `integrations.github[].token` | Token used to authenticate API/raw requests | `token: ${GITHUB_TOKEN}` (use env var) |

## Generate a GitHub Personal Access Token (PAT)

Steps to create a PAT:

1. In GitHub go to: Profile → Settings → Developer settings → Personal access tokens → Classic tokens → Generate new token (classic).
2. Give it a descriptive name (e.g., "Backstage"), choose an expiration, and grant the minimal scope(s) needed to read private repos — typically the `repo` scope.
3. Generate and copy the token; store it securely.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/cTFshlV6LNi9HF-G/images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/github-pat-classic-repo-scope-30d.jpg?fit=max&auto=format&n=cTFshlV6LNi9HF-G&q=85&s=eadade234b3acc61e05ebd0b44499c47" alt="A screenshot of the GitHub &#x22;New personal access token (classic)&#x22; settings page showing fields for the token note, expiration (30 days), and selectable scopes. The &#x22;repo&#x22; scope is checked among other permissions like workflow and package-related options." width="1920" height="1080" data-path="images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/github-pat-classic-repo-scope-30d.jpg" />
</Frame>

<Callout icon="warning" color="#FF6B6B">
  Personal access tokens are sensitive credentials. Grant the least privilege required (e.g., `repo` for reading private repos), and avoid long-lived tokens when possible. Use a secrets manager or short expirations in production.
</Callout>

## Set the token in the environment (recommended)

Export the token into the environment used by the Backstage backend process. For example, in a POSIX shell:

```bash theme={null}
export GITHUB_TOKEN="paste_your_token_here"
```

Then restart your Backstage backend so it picks up the environment variable (for example `yarn dev` or `yarn start` depending on your setup).

<Callout icon="lightbulb" color="#1CB2FE">
  Do not commit personal access tokens to source control. Use environment variables or a secrets manager for production deployments.
</Callout>

> Note: For local testing you can temporarily hardcode the token in `app-config.yaml`, but never commit such changes.

## Retry the Register an existing component flow

After restarting Backstage with the GitHub integration configured and the token available, retry the "Register an existing component" flow in the Backstage UI. Backstage should now be able to access the raw file on GitHub and import the entity.

Register an existing component — Import flow:

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/cTFshlV6LNi9HF-G/images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/backstage-register-component-wizard-github-import.jpg?fit=max&auto=format&n=cTFshlV6LNi9HF-G&q=85&s=eb13ee302f467bd7a963c30380f843c0" alt="A screenshot of the Backstage web UI showing the &#x22;Register an existing component&#x22; wizard with steps to select a URL and locations and an &#x22;Import&#x22; button. The right pane describes linking to an existing entity file or repository (GitHub) to add components to the catalog." width="1920" height="1080" data-path="images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/backstage-register-component-wizard-github-import.jpg" />
</Frame>

After the import completes, you can view the component in the catalog. For example, the imported `auth-service` component overview:

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/cTFshlV6LNi9HF-G/images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/backstage-auth-service-overview-warning.jpg?fit=max&auto=format&n=cTFshlV6LNi9HF-G&q=85&s=77bb4834254db67387721daa1a1ea344" alt="A screenshot of the Backstage web UI showing the &#x22;auth-service&#x22; component overview page with an About panel, Relations graph, and a warning about related entities not found. The left sidebar shows navigation items like Home, APIs, Docs, and Create." width="1920" height="1080" data-path="images/Prep-Course-Certified-Backstage-Associate-CBA-Certification/Catalog/Demo-Integrations-Private-Repository/backstage-auth-service-overview-warning.jpg" />
</Frame>

## Summary / Checklist

* Private repositories require a configured GitHub integration so Backstage can authenticate and read raw files.
* Add `raw.githubusercontent.com` to `reading.allow` and configure a `github` integration in `app-config.yaml`.
* Generate a GitHub PAT with the `repo` scope (least privilege) and set it via an environment variable (e.g., `GITHUB_TOKEN`).
* Restart the Backstage backend after configuration changes.
* Re-run "Register an existing component" to import the entity into the catalog.

Further reading and references:

* Backstage docs — Integrations: [https://backstage.io/docs/integrations](https://backstage.io/docs/integrations)
* GitHub docs — Creating a personal access token: [https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)

This completes the walkthrough for configuring Backstage to read catalog files from private GitHub repositories.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/certified-backstage-associate-cba/module/f9244f9d-083a-4acd-a518-549f54b644b5/lesson/0b0b01d9-69a2-4dab-a159-e9ae7c0bf049" />
</CardGroup>
