GitHub’s external custom properties let an outside system keep repository metadata synchronized without giving repository users an edit box in GitHub. A CMDB, service catalog, internal developer portal, or compliance system can remain the source of truth for values such as owner, service tier, lifecycle stage, and compliance status. GitHub announced the feature in public preview on September 29, 2026. See the announcement and the integration guide for the current preview behavior.
This solves a common governance problem: important repository context exists in one system, while GitHub rulesets, repository views, and engineering workflows need to use it. Instead of copying values by hand or allowing two systems to disagree, the external system writes a dedicated namespace that GitHub can read and target.
External properties versus normal custom properties
Use normal custom properties when GitHub should own the value. Organization owners can define and update those properties in GitHub or through the standard APIs. Use external custom properties when another system must own the value and continuously update it.
External values are read-only in the GitHub UI. That prevents a repository administrator from changing a service tier or compliance value in a place where the source system cannot see the edit. The external integration owns updates, and GitHub becomes a governed view of that context.
What you can do with the synced values
External properties can be used in the same places as GitHub-managed custom properties. That includes repository views, repository filtering, and ruleset targeting. For example, a platform team can target repositories where `service_tier=critical`, or show all repositories owned by a particular group without asking the group to maintain a second GitHub-only field.
The important design choice is to keep the property values useful for policy. Prefer stable, bounded fields such as `owner_team`, `service_tier`, `lifecycle`, `data_classification`, and `compliance_scope`. Avoid syncing a giant description field that cannot drive a filter or rule.
The integration model
GitHub’s documented integration uses a GitHub App. The app is the identity that reads from your external system and writes the external property values to repositories. Register the app installation with the organization, grant only the External custom properties for repositories permission it needs, and keep the source-system credentials outside the GitHub App code.
Public preview means the API and behavior can change. Keep the sync worker small, make retries safe, and record the source record ID and last successful sync time in your own system. Do not make a property update the only copy of ownership data.
Register the GitHub App installation
The registration gives an installation a display name and connects it to the organization’s external-property namespace. The app installation needs the admin permission to register itself. Later value updates use the write permission.
# Register the GitHub App installation for external properties
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_APP_INSTALLATION_TOKEN" \
-H "X-GitHub-Api-Version: 2026-03-10" \
https://api.github.com/orgs/ORG/properties/installations \
-d '{"installation_id":67890,"display_name":"service-catalog"}'Use your actual installation ID and keep the token in a secret manager. If the same installation is registered twice, GitHub returns an error rather than creating a second registration. Uninstalling the GitHub App removes the external properties created by that installation, so treat app lifecycle as data lifecycle too.
Update repository values in batches
The API supports two useful update shapes. You can update several properties for up to 30 repositories in one request, or update one property across up to 100 repositories. Choose the first when one source record changes several fields, and the second when a single property has changed for a larger group.
# Update multiple external properties for up to 30 repositories
curl -L -X PATCH \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_APP_INSTALLATION_TOKEN" \
-H "X-GitHub-Api-Version: 2026-03-10" \
https://api.github.com/orgs/ORG/properties/installations/values \
-d '{"repository_names":["payments-api","checkout-web"],"properties":[{"property_name":"service_tier","value":"critical"},{"property_name":"owner_team","value":"payments"}]}'A `null` property value removes the value from a repository. Decide whether a missing source record means unset, unknown, or preserve before writing the sync logic. Silent deletion is a common way to turn a temporary source outage into a policy gap.
Design a sync that fails safely
1. Choose the source system and define ownership for each property.
2. Map source records to immutable GitHub repository names or IDs.
3. Validate values before calling GitHub, including allowed states and team identifiers.
4. Batch writes within the API limits and retry only failed batches.
5. Store a sync cursor, source revision, and last successful update.
6. Alert when a repository disappears from the source or a value cannot be mapped.
7. Keep a documented manual recovery path for a bad sync.
Do not let the integration overwrite GitHub-managed properties with the same name. Use a clear namespace owned by the integration, such as `catalog_owner_team` or `cmdb_service_tier`, so a human can tell where a value comes from.
Use metadata to enforce policy
Once the values are synced, use them to target rulesets and saved views. Examples include requiring stronger branch protection for critical services, finding repositories without an owner, separating production and experimental repositories, and reviewing compliance status without maintaining a separate GitHub spreadsheet.
Start with visibility before enforcement. Create a view that shows the synced values, find missing or unexpected data, and compare the result with your source system. Add a ruleset only after the sync has a clear freshness signal and an owner for failures.
The short version
External custom properties make GitHub a useful policy surface without making it the owner of every business fact. Keep the source system authoritative, use a GitHub App with narrow permissions, batch updates, make missing data explicit, and validate the sync before using it to block changes.
