Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions app/cli/cmd/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ var (
attestationID string
)

// Legacy env variable
const robotAccountEnvVarName = "CHAINLOOP_ROBOT_ACCOUNT"

func newAttestationCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "attestation",
Expand All @@ -55,10 +52,6 @@ func newAttestationCmd() *cobra.Command {
return cmd.MarkFlagRequired("attestation-id")
}

if os.Getenv(tokenEnvVarName) != "" && os.Getenv(robotAccountEnvVarName) != "" {
return fmt.Errorf("both %s and %s env variables cannot be set at the same time", tokenEnvVarName, robotAccountEnvVarName)
}

return nil
},
}
Expand All @@ -69,10 +62,6 @@ func newAttestationCmd() *cobra.Command {
if attAPIToken == "" {
// Check first the new env variable
attAPIToken = os.Getenv(tokenEnvVarName)
// If it stills not set, use the legacy one for some time
if attAPIToken == "" {
attAPIToken = os.Getenv(robotAccountEnvVarName)
}
}

cmd.PersistentFlags().BoolVar(&GracefulExit, "graceful-exit", false, "exit 0 in case of error. NOTE: this flag will be removed once Chainloop reaches 1.0")
Expand Down
2 changes: 1 addition & 1 deletion app/cli/cmd/attestation_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func newAttestationAddCmd() *cobra.Command {
Use: "add",
Short: "add a material to the attestation",
Annotations: map[string]string{
useWorkflowRobotAccount: "true",
useAPIToken: "true",
},
Example: ` # Add a material to the attestation that is defined in the contract
chainloop attestation add --name <material-name> --value <material-value>
Expand Down
17 changes: 14 additions & 3 deletions app/cli/cmd/attestation_init.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 The Chainloop Authors.
// Copyright 2024 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,7 +38,14 @@ func newAttestationInitCmd() *cobra.Command {
Use: "init",
Short: "start attestation crafting process",
Annotations: map[string]string{
useWorkflowRobotAccount: "true",
useAPIToken: "true",
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if workflowName == "" {
return fmt.Errorf("workflow name is required, set it via --name flag or %s environment variable", workflowNameEnvVarName)
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
a, err := action.NewAttestationInit(
Expand Down Expand Up @@ -85,7 +92,11 @@ func newAttestationInitCmd() *cobra.Command {
cmd.Flags().BoolVarP(&force, "replace", "f", false, "replace any existing in-progress attestation")
cmd.Flags().BoolVar(&attestationDryRun, "dry-run", false, "do not record attestation in the control plane, useful for development")
cmd.Flags().IntVar(&contractRevision, "contract-revision", 0, "revision of the contract to retrieve, \"latest\" by default")
cmd.Flags().StringVar(&workflowName, "workflow-name", "", "name of the workflow to run the attestation. This is ignored when authentication is based on Robot Account")

// workflow-name has been replaced by --name flag
cmd.Flags().StringVar(&workflowName, "workflow-name", "", "name of the workflow to run the attestation")
cobra.CheckErr(cmd.Flags().MarkHidden("workflow-name"))
cmd.Flags().StringVar(&workflowName, "name", "", "name of the workflow to run the attestation")
if workflowName == "" {
workflowName = os.Getenv(workflowNameEnvVarName)
}
Expand Down
6 changes: 3 additions & 3 deletions app/cli/cmd/attestation_push.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ func newAttestationPushCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "push",
Short: "generate and push the attestation to the control plane",
Example: ` chainloop attestation push --key <key path>|<env://VAR_NAME> --token [robot-account-token] --annotation key=value,key2=val2
Example: ` chainloop attestation push --key <key path>|<env://VAR_NAME> --token [chainloop-token] --annotation key=value,key2=val2

# sign the resulting attestation using a cosign key present in the filesystem and stdin for the passphrase
# NOTE that the --token flag can be replaced by having the CHAINLOOP_TOKEN env variable
chainloop attestation push --key cosign.key --token [robot-account-token]
chainloop attestation push --key cosign.key --token [chainloop-token]

# or retrieve the key from an environment variable containing the private key
chainloop attestation push --key env://[ENV_VAR]
Expand All @@ -47,7 +47,7 @@ func newAttestationPushCmd() *cobra.Command {
# Or alternatively
chainloop attestation push --annotation key=value,key2=value2`,
Annotations: map[string]string{
useWorkflowRobotAccount: "true",
useAPIToken: "true",
},
RunE: func(cmd *cobra.Command, args []string) error {
info, err := executableInfo()
Expand Down
2 changes: 1 addition & 1 deletion app/cli/cmd/attestation_reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func newAttestationResetCmd() *cobra.Command {
Use: "reset",
Short: "mark current attestation process as canceled or failed",
Annotations: map[string]string{
useWorkflowRobotAccount: "true",
useAPIToken: "true",
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if trigger != triggerFailed && trigger != triggerCanceled {
Expand Down
2 changes: 1 addition & 1 deletion app/cli/cmd/attestation_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func newAttestationStatusCmd() *cobra.Command {
Use: "status",
Short: "check the status of the current attestation process",
Annotations: map[string]string{
useWorkflowRobotAccount: "true",
useAPIToken: "true",
},
RunE: func(cmd *cobra.Command, args []string) error {
a, err := action.NewAttestationStatus(
Expand Down
2 changes: 1 addition & 1 deletion app/cli/cmd/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ func newGracefulError(err error) error {

var ErrAttestationNotInitialized = errors.New("attestation not yet initialized, execute the init command first")
var ErrAttestationAlreadyExist = errors.New("attestation already initialized, to override it use the --replace flag`")
var ErrAttestationTokenRequired = errors.New("token required, please provide it via the pre-defined env variable or command flag")
var ErrAttestationTokenRequired = errors.New("chainloop Token required, please provide it via --token flag or CHAINLOOP_TOKEN environment variable")
5 changes: 2 additions & 3 deletions app/cli/cmd/organization_apitoken.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 The Chainloop Authors.
// Copyright 2024 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,8 +24,7 @@ func newOrganizationAPITokenCmd() *cobra.Command {
Use: "api-token",
Aliases: []string{"token"},
Short: "API token management",
Long: `Manage API tokens to authenticate with the Chainloop API.
NOTE: They are not meant to be used during the attestation process, for that purpose you'll need to use a robot accounts instead.`,
Long: "Manage API tokens to authenticate with the Chainloop API or perform attestations.",
}

cmd.AddCommand(newAPITokenCreateCmd(), newAPITokenListCmd(), newAPITokenRevokeCmd())
Expand Down
1 change: 0 additions & 1 deletion app/cli/cmd/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ const formatTable = "table"
type tabulatedData interface {
[]*action.WorkflowItem |
*action.AttestationStatusResult |
[]*action.WorkflowRobotAccountItem |
[]*action.WorkflowRunItem |
*action.WorkflowRunItemFull |
[]*action.WorkflowContractItem |
Expand Down
33 changes: 11 additions & 22 deletions app/cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,11 @@ var (
)

const (
useWorkflowRobotAccount = "withWorkflowRobotAccount"
appName = "chainloop"
useAPIToken = "withAPITokenAuth"
appName = "chainloop"
//nolint:gosec
tokenEnvVarName = "CHAINLOOP_TOKEN"
robotAccountAudience = "attestations.chainloop"
userAudience = "user-auth.chainloop"
tokenEnvVarName = "CHAINLOOP_TOKEN"
userAudience = "user-auth.chainloop"
//nolint:gosec
apiTokenAudience = "api-token-auth.chainloop"
// Follow the convention stated on https://consoledonottrack.com/
Expand Down Expand Up @@ -90,7 +89,7 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command {

apiToken, err := loadControlplaneAuthToken(cmd)
if err != nil {
return fmt.Errorf("loading controlplane auth token: %w", err)
return err
}

conn, err := grpcconn.New(viper.GetString(confOptions.controlplaneAPI.viperKey), apiToken, flagInsecure)
Expand Down Expand Up @@ -240,13 +239,12 @@ func cleanup(conn *grpc.ClientConn) error {
}

// Load the controlplane based on the following order:
// 1. If the CMD uses a robot account instead of the regular auth token we override it
// 2. If the CMD uses an API token flag/env variable we override it
// 3. If the CMD uses a config file we load it from there
// 1. If the CMD uses an API token flag/env variable we override it
// 2. If the CMD uses a config file we load it from there
func loadControlplaneAuthToken(cmd *cobra.Command) (string, error) {
// If the CMD uses a robot account instead of the regular auth token we override it
// If the CMD uses an API token instead of the regular OIDC auth token we override it
// TODO: the attestation CLI should get split from this one
if _, ok := cmd.Annotations[useWorkflowRobotAccount]; ok {
if _, ok := cmd.Annotations[useAPIToken]; ok {
if attAPIToken == "" {
return "", newGracefulError(ErrAttestationTokenRequired)
}
Expand All @@ -265,9 +263,8 @@ func loadControlplaneAuthToken(cmd *cobra.Command) (string, error) {
}

// parseToken the token and return the type of token. At the moment in Chainloop we have 3 types of tokens:
// 1. Robot account token
// 2. User account token
// 3. API token
// 1. User account token
// 2. API token
// Each one of them have an associated audience claim that we use to identify the type of token. If the token is not
// present, nor we cannot match it with one of the expected audience, return nil.
func parseToken(token string) (*parsedToken, error) {
Expand Down Expand Up @@ -322,14 +319,6 @@ func parseToken(token string) (*parsedToken, error) {
if userID, ok := claims["user_id"].(string); ok {
pToken.id = userID
}
case robotAccountAudience:
pToken.tokenType = "robot-account"
if tokenID, ok := claims["jti"].(string); ok {
pToken.id = tokenID
}
if orgID, ok := claims["org_id"].(string); ok {
pToken.orgID = orgID
}
default:
return nil, nil
}
Expand Down
18 changes: 0 additions & 18 deletions app/cli/cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@ func TestParseToken(t *testing.T) {
token string
want *parsedToken
}{
{
name: "robot account",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiJkZGRiODIwMS1lYWI2LTRlNjEtOTIwMS1mMTJiNDdjMDE4OTIiLCJ3b3JrZmxvd19pZCI6ImY0NmIzMDc5LTMwOGYtNGIwNC1hYjYwLTY3NDNmOGUzMGQzMyIsImlzcyI6ImNwLmNoYWlubG9vcCIsImF1ZCI6WyJhdHRlc3RhdGlvbnMuY2hhaW5sb29wIl0sImp0aSI6IjkzODI5NDE1LTA1ODYtNDFkYS05NTJkLTkyYTRjNDk1ZWEyMCJ9.3Af2C62PiODbEknhv47j0LHLuAgWLqvTrfmIzFjwPCM",
want: &parsedToken{
id: "93829415-0586-41da-952d-92a4c495ea20",
tokenType: "robot-account",
orgID: "dddb8201-eab6-4e61-9201-f12b47c01892",
},
},
{
name: "user account",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYmMwYjIxOTktY2E4NS00MmFiLWE4NTctMDQyZTljMTA5ZDQzIiwiaXNzIjoiY3AuY2hhaW5sb29wIiwiYXVkIjpbInVzZXItYXV0aC5jaGFpbmxvb3AiXSwiZXhwIjoxNzE1OTM1MjUwfQ.ounYshGtagtYQsVIzNeE0ztVYRXrmjFSpdmaTF4QvyY",
Expand All @@ -61,15 +52,6 @@ func TestParseToken(t *testing.T) {
tokenType: "api-token",
},
},
{
name: "old robot account",
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdfaWQiOiI5M2QwMjI3NS04NTNjLTRhZDYtOWQ2MC04ZjU2MmIxMjNmZDIiLCJ3b3JrZmxvd19pZCI6IjM1ZTZkOGIwLWE0OGYtNDFmYS05YmU3LWQ1OTM5YjJkZGUyNiIsImlzcyI6ImNwLmNoYWlubG9vcCIsImF1ZCI6WyJhdHRlc3RhdGlvbnMuY2hhaW5sb29wIl0sImp0aSI6ImUxZDUzOGQxLWI2MWQtNGY4MC1iZWQzLWM3MGE1NzRlOWI2NiJ9.81WltZtOno26oNydJ-YtHRwAIEmD2B4RgChhsS4yYVk",
want: &parsedToken{
id: "e1d538d1-b61d-4f80-bed3-c70a574e9b66",
tokenType: "robot-account",
orgID: "93d02275-853c-4ad6-9d60-8f562b123fd2",
},
},
{
name: "totally random token",
token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE3MTYxOTE2ODQsImV4cCI6MTc0NzcyNzY4NCwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.5UnBivwkQCG4qWgi-gWkJ-Dsd7-A9G_EVEvswODc7Kk",
Expand Down
6 changes: 3 additions & 3 deletions app/cli/cmd/workflow.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023 The Chainloop Authors.
// Copyright 2024 The Chainloop Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -23,9 +23,9 @@ func newWorkflowCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "workflow",
Aliases: []string{"wf"},
Short: "Workflow, contracts, robot-accounts and runs management in the control plane",
Short: "Workflow management in the control plane",
}

cmd.AddCommand(newWorkflowListCmd(), newWorkflowDescribeCmd(), newWorkflowCreateCmd(), newWorkflowUpdateCmd(), newWorkflowDeleteCmd(), newWorkflowRobotAccountCmd(), newWorkflowWorkflowRunCmd(), newWorkflowContractCmd(), newAttachedIntegrationCmd())
cmd.AddCommand(newWorkflowListCmd(), newWorkflowDescribeCmd(), newWorkflowCreateCmd(), newWorkflowUpdateCmd(), newWorkflowDeleteCmd(), newWorkflowWorkflowRunCmd(), newWorkflowContractCmd(), newAttachedIntegrationCmd())
return cmd
}
5 changes: 1 addition & 4 deletions app/cli/cmd/workflow_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

func newWorkflowCreateCmd() *cobra.Command {
var workflowName, description, project, team, contract string
var skipRACreate, public bool
var public bool

cmd := &cobra.Command{
Use: "create",
Expand Down Expand Up @@ -88,10 +88,7 @@ func newWorkflowCreateCmd() *cobra.Command {

cmd.Flags().StringVar(&team, "team", "", "team name")
cmd.Flags().StringVar(&contract, "contract", "", "the ID of an existing contract or the path/URL to a contract file. If not provided an empty one will be created.")

cmd.Flags().BoolVarP(&skipRACreate, "skip-robot-account-create", "s", false, "Skip creating a Robot Account for this workflow.")
cmd.Flags().BoolVar(&public, "public", false, "is the workflow public")

cmd.Flags().SortFlags = false

return cmd
Expand Down
31 changes: 0 additions & 31 deletions app/cli/cmd/workflow_robotaccount.go

This file was deleted.

46 changes: 0 additions & 46 deletions app/cli/cmd/workflow_robotaccount_create.go

This file was deleted.

Loading