octo-sts / app

A GitHub App that acts like a Security Token Service (STS) for the Github API
Apache License 2.0
139 stars 15 forks source link

Policy Definitions for STS Policies #469

Open karlhaworth opened 2 months ago

karlhaworth commented 2 months ago

Policy Definitions for STS Policies

Outcome - Deny undesired cross-org access

@wlynch mentioned possibly incorporating into -> https://github.com/octo-sts/app/blob/main/pkg/webhook/webhook.go

Problem

In large orgs, if someone were able to commit a file with an undesired org, this undesired org has access to a private org.

As a octo-sts implementor, I want to restrict the orgs that can obtain tokens in octo-sts So that I can be assured no unauthorized org can ever gain access using octo-sts

Potential Solution

Envisioning a way to instruct Octo-STS to only hand out tokens to valid declared orgs in a policy.

In the STS policies there's already the subject_pattern being used. I am proposing to use the org bounded claim instead of repo if possible for this.

The policy definition would live at the org level under something like .github/.chainguard/policy.sts.yaml.

kind: policy

issuer: https://token.actions.githubusercontent.com
subject_patterns:
  - org:AATestOrg

figured maybe we'd need a kind to be added?

karlhaworth commented 2 months ago

@wlynch

what about something like the below in pkg/octosts/octosts.go? The ALLOWED_ORGS can be a comma separated list. Similar to what I saw here https://github.com/octo-sts/app/pull/476/files#diff-3e455a0e8a009c415c69c239ee08525a8f1ae4c0a127fdd94297ec0b1ef262ce

real quick stab at this.

    parsedToken, err := jwt.Parse(bearer, nil)
    if parsedToken == nil {
        return nil, err
    }
    claims, _ := parsedToken.Claims.(jwt.MapClaims)

    orgs := strings.Split(s.orgs, ",")

    clog.FromContext(ctx).Infof("claims: %#v", claims)

    repositoryOwner := claims["repository_owner"].(string)
    isValidOwner := false
    for _, org := range orgs {
        if org == repositoryOwner {
            isValidOwner = true
            break
        }
    }

    if !isValidOwner {
        return nil, status.Errorf(codes.PermissionDenied, "invalid repository owner")
    }

Branch -> https://github.com/octo-sts/app/compare/main...AmericanAirlines:octo-sts-app:feat--define-allowed_organizations-for-repository_owner