Skip to content

Repository Ownership

Shoehorn tracks ownership of repositories through multiple mechanisms: GitHub topics, service manifests, and Forge-created repositories. This guide covers how ownership is established and resolved.

The simplest way to assign ownership is with GitHub topics. No manifest files required.

Shoehorn recognizes all of these patterns:

GitHub TopicMaps to Team
owner-platform-teamplatform-team
owner:platform-teamplatform-team
team-beta-teambeta-team
team:beta-teambeta-team

Recommended for new repositories:

  • Use owner-<team-slug> when you want the topic itself to be treated as the explicit ownership signal.
  • Use team-<team-slug> when you want a lighter-weight team ownership topic.

Via GitHub UI:

  1. Go to your repository on GitHub
  2. Click the gear icon next to About
  3. In the Topics field, add owner-<your-team-slug> or team-<your-team-slug>
  4. Click Save changes

Via GitHub API:

Terminal window
curl -X PUT https://api.github.com/repos/<owner>/<repo>/topics \
-H "Authorization: token <github-token>" \
-H "Accept: application/vnd.github+json" \
-d '{"names": ["owner-platform-team", "golang", "microservice"]}'

Via Forge (automatic):

When creating a repository through Forge, pass topics directly to github.repo.create:

steps:
- id: create-repo
name: Create GitHub repository
action: github.repo.create
inputs:
owner: my-org
name: "${{ inputs.name }}"
description: "Service created via Forge"
private: true
topics: ["owner-${{ inputs.owner }}", "golang", "microservice"]
  1. The crawler scans repositories in configured GitHub organizations
  2. Topics matching owner-*, owner:*, team-*, or team:* are extracted
  3. The prefix is stripped to get the team slug
  4. The repository is linked to the matching Shoehorn team

A repository can have many topics. Only owner-*, owner:*, team-*, and team:* affect ownership. All other topics are imported as entity tags.

If multiple ownership topics are present, Shoehorn imports all matching candidates. Use a single ownership topic per repository to keep ownership unambiguous.

For explicit ownership, add a .shoehorn/manifest.yml to your repository:

schemaVersion: 1
service:
id: payment-api
name: Payment API
type: service
owner:
- type: team
id: payments-team

Manifest ownership has the highest priority and overrides topics and annotations.

Forge workflows can create repositories with ownership pre-configured.

Example: Create a Repository with Ownership

Section titled “Example: Create a Repository with Ownership”
version: "1.0.0"
metadata:
name: create-service
displayName: Create Service Repository
category: repository
inputs:
type: object
required: [name, owner]
properties:
name:
type: string
title: Service Name
owner:
type: string
title: Owning Team
description: Team slug (e.g., platform-team)
steps:
- id: create-repo
name: Create GitHub repository
action: github.repo.create
inputs:
owner: my-org
name: "${{ inputs.name }}"
description: "Service created via Forge"
private: true
topics: ["owner-${{ inputs.owner }}", "shoehorn-managed"]
- id: register
name: Register in catalog
action: catalog.entity.register
inputs:
serviceId: "${{ inputs.name }}"
name: "${{ inputs.name }}"
type: service
owner: "${{ inputs.owner }}"

For repositories created directly on GitHub (not through Forge), ownership is established by:

  1. Adding a topic — Add owner-<team-slug> or team-<team-slug> to the repository topics
  2. Adding a manifest — Create .shoehorn/manifest.yml with an owner field
  3. Waiting for discovery — The crawler picks up new repositories on its next scan (or immediately via the repository.created webhook)

When multiple sources provide ownership, the highest-priority source wins:

PrioritySourceExample
1 (highest)Manifest owner fieldowner: [{type: team, id: payments}]
2Kubernetes annotationshoehorn.dev/owner: payments
3 (lowest)GitHub topicowner-platform-team or team-beta-team

If a manifest sets an owner, the GitHub topic is ignored for ownership but still tracked as metadata.

The scorecard rule team-topic checks if a repository has an ownership topic. This contributes to the ownership category score, encouraging teams to declare ownership for all repositories.