Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Code reviews are required for all submissions via GitHub pull requests.
- when adding new inedexes, make sure to update the generated sql migraiton files and make them CREATE INDEX CONCURRENTLY and set -- atlas:txmode none at the top
- after updating protos, make sure to run `buf format -w`
- Please avoid sycophantic commentary like ‘You’re absolutely correct!’ or ‘Brilliant idea!’
- For each file you modify, update the license header so the last year is the current year. For example, `Copyright 2023` becomes `Copyright 2023-2026`. If it already ends with the current year, no change needed. If there's no license header, create one with the current year.
- For each file you modify, update the license header so the last year is the current year. For example, `Copyright 2023` becomes `Copyright 2023-2026`. If it already ends with the current year, no change needed. New files should use only the current year (e.g., `Copyright 2026`), not a range.
- if you add any new dependency to a constructor, remember to run wire ./...
- when creating PR message, keep it high-level, what functionality was added, don't add info about testing, no icons, no info about how the message was generated.
- app/controlplane/api/gen/frontend/google/protobuf/descriptor.ts is a special case that we don't want to upgrade, so if it upgrades, put it back to main
Expand Down
4 changes: 4 additions & 0 deletions app/cli/cmd/organization_describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func contextTableOutput(config *action.ConfigContextItem) error {
orgInfo += fmt.Sprintf("\nPolicy allowed hostnames: %v", strings.Join(m.Org.PolicyAllowedHostnames, ", "))
}

if m.Org.APITokenMaxDaysInactive != nil {
orgInfo += fmt.Sprintf("\nAPI token auto-revoke after: %s days inactive", *m.Org.APITokenMaxDaysInactive)
}

gt.AppendRow(table.Row{"Organization", orgInfo})
}

Expand Down
18 changes: 17 additions & 1 deletion app/cli/cmd/organization_update.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023-2025 The Chainloop Authors.
// Copyright 2023-2026 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 @@ -16,6 +16,9 @@
package cmd

import (
"fmt"
"strconv"

"github.com/chainloop-dev/chainloop/app/cli/pkg/action"
"github.com/spf13/cobra"
)
Expand All @@ -27,6 +30,7 @@ func newOrganizationUpdateCmd() *cobra.Command {
policiesAllowedHostnames []string
preventImplicitWorkflowCreation bool
restrictContractCreation bool
apiTokenMaxDaysInactive string
)

cmd := &cobra.Command{
Expand All @@ -50,6 +54,17 @@ func newOrganizationUpdateCmd() *cobra.Command {
opts.RestrictContractCreation = &restrictContractCreation
}

if cmd.Flags().Changed("api-token-max-days-inactive") {
days, err := strconv.Atoi(apiTokenMaxDaysInactive)
if err != nil {
return fmt.Errorf("invalid value %q: must be a number of days (0 to disable)", apiTokenMaxDaysInactive)
}
if days < 0 || days > 365 {
return fmt.Errorf("api-token-max-days-inactive must be between 0 (disabled) and 365")
}
opts.APITokenMaxDaysInactive = &days
}

_, err := action.NewOrgUpdate(ActionOpts).Run(cmd.Context(), orgName, opts)
if err != nil {
return err
Expand All @@ -68,5 +83,6 @@ func newOrganizationUpdateCmd() *cobra.Command {
cmd.Flags().StringSliceVar(&policiesAllowedHostnames, "policies-allowed-hostnames", []string{}, "set the allowed hostnames for the policy engine")
cmd.Flags().BoolVar(&preventImplicitWorkflowCreation, "prevent-implicit-workflow-creation", false, "prevent workflows and projects from being created implicitly during attestation init")
cmd.Flags().BoolVar(&restrictContractCreation, "restrict-contract-creation", false, "restrict contract creation (org-level and project-level) to only organization admins (owner/admin roles)")
cmd.Flags().StringVar(&apiTokenMaxDaysInactive, "api-token-max-days-inactive", "", "maximum days of inactivity before API tokens are auto-revoked (e.g. '90', '0' to disable)")
return cmd
}
1 change: 1 addition & 0 deletions app/cli/documentation/cli-reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2775,6 +2775,7 @@ chainloop organization update [flags]
Options

```
--api-token-max-days-inactive string maximum days of inactivity before API tokens are auto-revoked (e.g. '90', '0' to disable)
--block set the default policy violation blocking strategy
-h, --help help for update
--name string organization name
Expand Down
8 changes: 7 additions & 1 deletion app/cli/pkg/action/membership_list.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024 The Chainloop Authors.
// Copyright 2024-2026 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 @@ -35,6 +35,7 @@ type OrgItem struct {
PolicyViolationBlockingStrategy string `json:"policyViolationBlockingStrategy"`
PolicyAllowedHostnames []string `json:"policyAllowedHostnames,omitempty"`
PreventImplicitWorkflowCreation bool `json:"preventImplicitWorkflowCreation"`
APITokenMaxDaysInactive *string `json:"apiTokenMaxDaysInactive,omitempty"`
}

type MembershipItem struct {
Expand Down Expand Up @@ -145,6 +146,11 @@ func pbOrgItemToAction(in *pb.OrgItem) *OrgItem {
i.PolicyViolationBlockingStrategy = PolicyViolationBlockingStrategyAdvisory
}

if in.ApiTokenMaxDaysInactive != nil {
s := fmt.Sprintf("%d", in.GetApiTokenMaxDaysInactive())
i.APITokenMaxDaysInactive = &s
}

return i
}

Expand Down
15 changes: 14 additions & 1 deletion app/cli/pkg/action/org_update.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2023-2025 The Chainloop Authors.
// Copyright 2023-2026 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 @@ -17,6 +17,7 @@ package action

import (
"context"
"fmt"

pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
)
Expand All @@ -34,6 +35,9 @@ type NewOrgUpdateOpts struct {
PoliciesAllowedHostnames *[]string
PreventImplicitWorkflowCreation *bool
RestrictContractCreation *bool
// APITokenMaxDaysInactive is the maximum number of days a token can be inactive before auto-revocation.
// 0 means disabled.
APITokenMaxDaysInactive *int
}

func (action *OrgUpdate) Run(ctx context.Context, name string, opts *NewOrgUpdateOpts) (*OrgItem, error) {
Expand All @@ -51,6 +55,15 @@ func (action *OrgUpdate) Run(ctx context.Context, name string, opts *NewOrgUpdat
payload.UpdatePoliciesAllowedHostnames = true
}

if opts.APITokenMaxDaysInactive != nil {
v := *opts.APITokenMaxDaysInactive
if v < 0 || v > 365 {
return nil, fmt.Errorf("api_token_max_days_inactive must be between 0 and 365")
}
days := int32(v)
payload.ApiTokenMaxDaysInactive = &days
}

resp, err := client.Update(ctx, payload)
if err != nil {
return nil, err
Expand Down
23 changes: 17 additions & 6 deletions app/controlplane/api/controlplane/v1/organization.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion app/controlplane/api/controlplane/v1/organization.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024-2025 The Chainloop Authors.
// Copyright 2024-2026 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 @@ -99,6 +99,9 @@ message OrganizationServiceUpdateRequest {

// restrict_contract_creation_to_org_admins restricts contract creation (org-level and project-level) to only organization admins (owner/admin roles)
optional bool restrict_contract_creation_to_org_admins = 6;

// Maximum days of inactivity before API tokens are auto-revoked. Set to 0 to disable.
optional int32 api_token_max_days_inactive = 7;
}

message OrganizationServiceUpdateResponse {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 18 additions & 6 deletions app/controlplane/api/controlplane/v1/response_messages.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion app/controlplane/api/controlplane/v1/response_messages.proto
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2024-2025 The Chainloop Authors.
// Copyright 2024-2026 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 @@ -286,6 +286,8 @@ message OrgItem {
bool prevent_implicit_workflow_creation = 7;
// restrict_contract_creation_to_org_admins restricts contract creation (org-level and project-level) to only organization admins (owner/admin roles)
bool restrict_contract_creation_to_org_admins = 8;
// Maximum days of inactivity before API tokens are auto-revoked. Absent if disabled.
optional int32 api_token_max_days_inactive = 9;

enum PolicyViolationBlockingStrategy {
POLICY_VIOLATION_BLOCKING_STRATEGY_UNSPECIFIED = 0;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading