Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

feat/sg: add 'sg sams' commands 'create-client-token' and 'introspect-token'#62883

Merged
bobheadxi merged 4 commits intomainfrom
sg-sams-commands
May 28, 2024
Merged

feat/sg: add 'sg sams' commands 'create-client-token' and 'introspect-token'#62883
bobheadxi merged 4 commits intomainfrom
sg-sams-commands

Conversation

@bobheadxi
Copy link
Member

@bobheadxi bobheadxi commented May 23, 2024

Right now, developing SAMS clients involves raw cURL commands (see operator cheat sheet) (which is fine), but other steps like "testing auth" require using accounts-clients-example, which isn't very well documented and requires a bit of hand-wringing to get to and start using.

We previously talked about making a SAMS-specific CLI, but IMO that's a pretty big pain point if we want SAMS integration adoption when everything else lives in sg, and all the nice tooling lives here as well.

This PR migrates the next steps after using cURL to set up clients (create-client-token and introspect-token) from accounts-clients-example to a new sg sams toolchain for better DX (docs, completions, flags)

Test plan

export SG_SAMS_CLIENT_ID="..."
export SG_SAMS_CLIENT_SECRET="..."
sg sams create-client-token -s 'enterprise_portal::codyaccess::read'

Copy link
Contributor

@chrsmith chrsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We previously talked about making a SAMS-specific CLI, but IMO that's a pretty big pain point if we want SAMS integration adoption when everything else lives in sg, and all the nice tooling lives here as well.

Directionally, this sounds like the right call. (Though I still liked the idea of a Sam Adams 🍺 sams-admin tool 😢.)

In case it helps, these are the things that I've needed to do as an admin of a SAMS integration:

CRUD on the scopes that a SAMS client can send in a request. (e.g. authorize "my app" to send tokens with "your app"'s permissions.) It seems like we'd need to be careful about how we expose that type of functionality though. (e.g. requiring that only an admin of "your app" can update "my app" to issue scopes for "your app", etc.)

return errors.Wrap(err, "generate token")
}

data, err := json.MarshalIndent(token, "", " ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not to over-think it, but it would be nice to separate concerns from "CLI tooling stuff" from "SAMS client interactions"?

e.g. within this file, maybe have a:

// samsClientAdmin is an API client for interacting with
// the SAMS APIs on behalf of a SAMS client, e.g. an OAuth
// app that _uses_ SAMS.
type samsClientAdmin struct {
   TokenSource ouath.TokenSource
}

// GetClientToken returns the current OAuth access token generated from
// the underlying token source.
func (sac *samsAdminClient) GetClientToken() string { ... }

// And later...
func (sac *samsAdminClient) ListScopes() ([]sdk.Scope, error) { ... }
func (sac *samsAdminClient) AddScopeToApp(newScope sdk.Scope) error { ... }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm inclined to keep this as is for now - I don't think this makes the callsite here much simpler (e.g. I don't think this client type should handle JSON marshalling, so the callsite still needs to handle the get-token error and then the JSON marshalling), and in between the other client types (oauth2.TokenSource is arguably a client type, as the .Token() gives us a structured type and whatnot with the credentials, as well as the existing sams.ClientV1) we already have a lot of logic that is separated from the CLI tooling stuff.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words, what we have here is basically already all CLI concerns (constructing type from flag, doing the thing, checking the error, dumping the output appropriately)

@bobheadxi
Copy link
Member Author

In case it helps, these are the things that I've needed to do as an admin of a SAMS integration:

It does help; I'd love to expand on the tooling here for all your SAMS-integration-development needs 😁 once @unknwon gets the chance to review, I'll open some tickets tracking some follow-up ideas

bobheadxi referenced this pull request May 27, 2024
…ess (#62771)

This PR exposes the data layer implemented in https://github.com/sourcegraph/sourcegraph/pull/62706 via the Enterprise Portal API. We register the services proposed in #62263 and also set up tooling like gRPC UI locally for DX.

Auth is via SAMS M2M; sourcegraph/sourcegraph-accounts-sdk-go#28 and sourcegraph/sourcegraph-accounts#227 rolls out the new scopes, and sourcegraph/managed-services#1474 adds credentials for the enterprise-portal-dev deployment.

Closes CORE-112

## Test plan

https://github.com/sourcegraph/sourcegraph/pull/62706 has extensive testing of the data layer, and this PR expands on it a little bit. I tested the RPC layer by hand:

Create SAMS client for Enterprise Portal Dev in **accounts.sgdev.org**:

```sh
curl -s -X POST \
        -H "Authorization: Bearer $MANAGEMENT_SECRET" \
        https://accounts.sgdev.org/api/management/v1/identity-provider/clients \
--data '{"name": "enterprise-portal-dev", "scopes": [], "redirect_uris": ["https://enterprise-portal.sgdev.org"]}' | jq
```

Configure `sg.config.overwrite.yaml`

```yaml
  enterprise-portal:
    env:
      SRC_LOG_LEVEL: debug
      # sams-dev
      SAMS_URL: https://accounts.sgdev.org
      ENTERPRISE_PORTAL_SAMS_CLIENT_ID: "sams_cid_..."
      ENTERPRISE_PORTAL_SAMS_CLIENT_SECRET: "sams_cs_..."
```

Create a test client (later, we will do the same thing for Cody Gateway), also in **accounts.sgdev.org**:

```sh
curl -s -X POST \
        -H "Authorization: Bearer $MANAGEMENT_SECRET" \
        https://accounts.sgdev.org/api/management/v1/identity-provider/clients \
--data '{"name": "enterprise-portal-dev-reader", "scopes": ["enterprise_portal::codyaccess::read", "enterprise_portal::subscription::read"], "redirect_uris": ["https://enterprise-portal.sgdev.org"]}' | jq
```

Then:

```
sg run enterprise-portal
```

Navigate to the locally-enabled gRPC debug UI at http://localhost:6081/debug/grcpui, using https://github.com/sourcegraph/sourcegraph/pull/62883 to get an access token from our test client to add in the request metadata:

```sh
sg sams create-client-token -s 'enterprise_portal::codyaccess::read'
```

I'm using some local subscriptions I've made previously in `sg start dotcom`:

![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/a55c6f0d-b0ae-4e68-8e4c-ccb6e2cc442d)

![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/19d18104-1051-4a82-abe0-58010dd13a27)

Without a valid authorization header:

![image](https://github.com/sourcegraph/sourcegraph/assets/23356519/c9cf4c89-9902-48f8-ac41-daf9a63ca789)

Verified a lookup using the returned access tokens also works

---------

Co-authored-by: Jean-Hadrien Chabran <jh@chabran.fr>
Co-authored-by: Joe Chen <joe@sourcegraph.com>
@unknwon
Copy link
Contributor

unknwon commented May 27, 2024

In case it helps, these are the things that I've needed to do as an admin of a SAMS integration:

It does help; I'd love to expand on the tooling here for all your SAMS-integration-development needs 😁 once @unknwon gets the chance to review, I'll open some tickets tracking some follow-up ideas

The direction sounds good, tho I'd want SAMS to first stop using shared-static management secret, e.g. somehow supporting/take advantage of (validating) credentials produced by gcloud auth application-default.

Copy link
Contributor

@unknwon unknwon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

bobheadxi and others added 2 commits May 28, 2024 12:35
Co-authored-by: Joe Chen <joe@sourcegraph.com>
@bobheadxi bobheadxi enabled auto-merge (squash) May 28, 2024 19:36
@bobheadxi bobheadxi merged commit de9a31a into main May 28, 2024
@bobheadxi bobheadxi deleted the sg-sams-commands branch May 28, 2024 21:08
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants