Skip to content

Commit

Permalink
make oauth redirect URL configurable (#358)
Browse files Browse the repository at this point in the history
Signed-off-by: Brian DeHamer <bdehamer@github.com>
  • Loading branch information
bdehamer committed Mar 21, 2023
1 parent f9e8492 commit 54d6de4
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-bees-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'sigstore': minor
---

Adds new `redirectURL` config option when signing with an OAuth identity provider
2 changes: 1 addition & 1 deletion src/__tests__/identity/oauth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jest.mock('child_process', () => ({
describe('OAuthProvider', () => {
const baseURL = 'http://localhost:8080';
const issuer = new Issuer(baseURL);
const subject = new OAuthProvider(issuer, 'sigstore', '');
const subject = new OAuthProvider({ issuer, clientID: 'sigstore' });

const mockedExec = jest.mocked(child_process.exec);

Expand Down
1 change: 1 addition & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ function printUsage() {
const signOptions = {
oidcClientID: 'sigstore',
oidcIssuer: 'https://oauth2.sigstore.dev/auth',
oidcRedirectURL: process.env.OIDC_REDIRECT_URL,
rekorURL: sigstore.DEFAULT_REKOR_URL,
};

Expand Down
18 changes: 12 additions & 6 deletions src/identity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,18 @@ import { Provider } from './provider';
* @param clientSecret Client secret for the issuer (optional)
* @returns {Provider}
*/
function oauthProvider(
issuer: string,
clientID: string,
clientSecret?: string
): Provider {
return new OAuthProvider(new Issuer(issuer), clientID, clientSecret);
function oauthProvider(options: {
issuer: string;
clientID: string;
clientSecret?: string;
redirectURL?: string;
}): Provider {
return new OAuthProvider({
issuer: new Issuer(options.issuer),
clientID: options.clientID,
clientSecret: options.clientSecret,
redirectURL: options.redirectURL,
});
}

/**
Expand Down
34 changes: 24 additions & 10 deletions src/identity/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import { crypto, encoding as enc } from '../util';
import { Issuer } from './issuer';
import { Provider } from './provider';

interface OAuthProviderOptions {
issuer: Issuer;
clientID: string;
clientSecret?: string;
redirectURL?: string;
}

export class OAuthProvider implements Provider {
private clientID: string;
private clientSecret: string;
Expand All @@ -32,10 +39,11 @@ export class OAuthProvider implements Provider {
private state: string;
private redirectURI?: string;

constructor(issuer: Issuer, clientID: string, clientSecret?: string) {
this.clientID = clientID;
this.clientSecret = clientSecret || '';
this.issuer = issuer;
constructor(options: OAuthProviderOptions) {
this.clientID = options.clientID;
this.clientSecret = options.clientSecret || '';
this.issuer = options.issuer;
this.redirectURI = options.redirectURL;
this.codeVerifier = generateRandomString(32);
this.state = generateRandomString(16);
}
Expand All @@ -52,9 +60,19 @@ export class OAuthProvider implements Provider {
const server = http.createServer();
const sockets = new Set<Socket>();

// Start server and wait till it is listening
// Start server and wait till it is listening. If a redirect URL was
// provided, use that. Otherwise, use a random port and construct the
// redirect URL.
await new Promise<void>((resolve) => {
server.listen(0, resolve);
if (this.redirectURI) {
const url = new URL(this.redirectURI);
server.listen(Number(url.port), url.hostname, resolve);
} else {
server.listen(0, resolve);
// Get port the server is listening on and construct the server URL
const port = (server.address() as AddressInfo).port;
this.redirectURI = `http://localhost:${port}`;
}
});

// Keep track of connections to the server so we can force a shutdown
Expand All @@ -65,10 +83,6 @@ export class OAuthProvider implements Provider {
});
});

// Get port the server is listening on and construct the server URL
const port = (server.address() as AddressInfo).port;
this.redirectURI = `http://localhost:${port}`;

const result = new Promise<string>((resolve, reject) => {
// Set-up handler for post-auth redirect
server.on('request', (req, res) => {
Expand Down
18 changes: 12 additions & 6 deletions src/sigstore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export type SignOptions = {
oidcIssuer?: string;
oidcClientID?: string;
oidcClientSecret?: string;
oidcRedirectURL?: string;
} & TLogOptions;

export type VerifyOptions = {
Expand All @@ -63,7 +64,11 @@ type Bundle = sigstore.SerializedBundle;

type IdentityProviderOptions = Pick<
SignOptions,
'identityToken' | 'oidcIssuer' | 'oidcClientID' | 'oidcClientSecret'
| 'identityToken'
| 'oidcIssuer'
| 'oidcClientID'
| 'oidcClientSecret'
| 'oidcRedirectURL'
>;

function createCAClient(options: { fulcioURL?: string }): CA {
Expand Down Expand Up @@ -148,11 +153,12 @@ function configureIdentityProviders(
idps.push(identity.ciContextProvider());
if (options.oidcIssuer && options.oidcClientID) {
idps.push(
identity.oauthProvider(
options.oidcIssuer,
options.oidcClientID,
options.oidcClientSecret
)
identity.oauthProvider({
issuer: options.oidcIssuer,
clientID: options.oidcClientID,
clientSecret: options.oidcClientSecret,
redirectURL: options.oidcRedirectURL,
})
);
}
}
Expand Down

0 comments on commit 54d6de4

Please sign in to comment.