Skip to content
Draft
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,4 @@ hack/

# Personal exports
*.csv
components/credential-sidecars/entrypoint/credential-entrypoint
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
.PHONY: setup-minio minio-console minio-logs minio-status
.PHONY: validate-makefile lint-makefile check-shell makefile-health benchmark benchmark-ci
.PHONY: _create-operator-config _auto-port-forward _show-access-info _kind-load-images
.PHONY: build-credential-sidecars build-credential-github build-credential-jira build-credential-k8s build-credential-google

# Default target
.DEFAULT_GOAL := help
Expand Down Expand Up @@ -67,6 +68,10 @@ STATE_SYNC_IMAGE ?= vteam_state_sync:$(IMAGE_TAG)
PUBLIC_API_IMAGE ?= vteam_public_api:$(IMAGE_TAG)
API_SERVER_IMAGE ?= vteam_api_server:$(IMAGE_TAG)
OBSERVABILITY_DASHBOARD_IMAGE ?= vteam_observability_dashboard:$(IMAGE_TAG)
GITHUB_MCP_IMAGE ?= vteam_credential_github:$(IMAGE_TAG)
JIRA_MCP_IMAGE ?= vteam_credential_jira:$(IMAGE_TAG)
K8S_MCP_IMAGE ?= vteam_credential_k8s:$(IMAGE_TAG)
GOOGLE_MCP_IMAGE ?= vteam_credential_google:$(IMAGE_TAG)

# kind-local overlay always references localhost/vteam_* images.
# Podman produces this prefix natively; for Docker we tag before loading.
Expand Down Expand Up @@ -221,6 +226,36 @@ build-observability-dashboard: ## Build observability dashboard image
-t $(OBSERVABILITY_DASHBOARD_IMAGE) .
@echo "$(COLOR_GREEN)✓$(COLOR_RESET) Observability dashboard built: $(OBSERVABILITY_DASHBOARD_IMAGE)"

build-credential-sidecars: build-credential-github build-credential-jira build-credential-k8s build-credential-google ## Build all credential sidecar images

build-credential-github: ## Build GitHub credential sidecar image
@echo "$(COLOR_BLUE)▶$(COLOR_RESET) Building GitHub credential sidecar with $(CONTAINER_ENGINE)..."
@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \
-f components/credential-sidecars/github/Dockerfile \
-t $(GITHUB_MCP_IMAGE) .
@echo "$(COLOR_GREEN)✓$(COLOR_RESET) GitHub credential sidecar built: $(GITHUB_MCP_IMAGE)"

build-credential-jira: ## Build Jira credential sidecar image
@echo "$(COLOR_BLUE)▶$(COLOR_RESET) Building Jira credential sidecar with $(CONTAINER_ENGINE)..."
@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \
-f components/credential-sidecars/jira/Dockerfile \
-t $(JIRA_MCP_IMAGE) .
@echo "$(COLOR_GREEN)✓$(COLOR_RESET) Jira credential sidecar built: $(JIRA_MCP_IMAGE)"

build-credential-k8s: ## Build K8s credential sidecar image
@echo "$(COLOR_BLUE)▶$(COLOR_RESET) Building K8s credential sidecar with $(CONTAINER_ENGINE)..."
@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \
-f components/credential-sidecars/k8s/Dockerfile \
-t $(K8S_MCP_IMAGE) .
@echo "$(COLOR_GREEN)✓$(COLOR_RESET) K8s credential sidecar built: $(K8S_MCP_IMAGE)"

build-credential-google: ## Build Google credential sidecar image
@echo "$(COLOR_BLUE)▶$(COLOR_RESET) Building Google credential sidecar with $(CONTAINER_ENGINE)..."
@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) $(BUILD_FLAGS) \
-f components/credential-sidecars/google/Dockerfile \
-t $(GOOGLE_MCP_IMAGE) .
@echo "$(COLOR_GREEN)✓$(COLOR_RESET) Google credential sidecar built: $(GOOGLE_MCP_IMAGE)"

Comment on lines +229 to +258
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Declare new credential-sidecar targets as .PHONY.

The targets added at Lines 228, 230, 237, 243, and 249 are missing from .PHONY (Lines 1-13). If same-named files appear, recipes may not run.

Suggested patch
-.PHONY: _create-operator-config _auto-port-forward _show-access-info _kind-load-images
+.PHONY: _create-operator-config _auto-port-forward _show-access-info _kind-load-images
+.PHONY: build-credential-sidecars build-credential-github build-credential-jira build-credential-k8s build-credential-google
🧰 Tools
🪛 checkmake (0.3.2)

[warning] 228-228: Target "build-credential-sidecars" should be declared PHONY.

(phonydeclared)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 228 - 254, Add the new Makefile targets to the .PHONY
declaration so their recipes always run: include build-credential-sidecars,
build-credential-github, build-credential-jira, build-credential-k8s, and
build-credential-google in the existing .PHONY list (update the .PHONY line near
the top where other phony targets are declared) to prevent name collisions with
files of the same names.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Credential sidecar build targets are currently orphaned from primary workflows.

At Line 228 you add sidecar build targets, but build-all (Line 170), push-all (Line 299), and _kind-load-images (Line 1263) still omit these images. This means make kind-up LOCAL_IMAGES=true and make push-all can skip sidecar images even when sidecars are required.

Suggested patch
-build-all: build-frontend build-backend build-operator build-runner build-state-sync build-public-api build-api-server build-observability-dashboard ## Build all container images
+build-all: build-frontend build-backend build-operator build-runner build-state-sync build-public-api build-api-server build-observability-dashboard build-credential-sidecars ## Build all container images
@@
-	`@for` image in $(FRONTEND_IMAGE) $(BACKEND_IMAGE) $(OPERATOR_IMAGE) $(RUNNER_IMAGE) $(STATE_SYNC_IMAGE) $(PUBLIC_API_IMAGE) $(API_SERVER_IMAGE) $(OBSERVABILITY_DASHBOARD_IMAGE); do \
+	`@for` image in $(FRONTEND_IMAGE) $(BACKEND_IMAGE) $(OPERATOR_IMAGE) $(RUNNER_IMAGE) $(STATE_SYNC_IMAGE) $(PUBLIC_API_IMAGE) $(API_SERVER_IMAGE) $(OBSERVABILITY_DASHBOARD_IMAGE) $(GITHUB_MCP_IMAGE) $(JIRA_MCP_IMAGE) $(K8S_MCP_IMAGE) $(GOOGLE_MCP_IMAGE); do \
@@
-	`@for` img in $(BACKEND_IMAGE) $(FRONTEND_IMAGE) $(OPERATOR_IMAGE) $(RUNNER_IMAGE) $(STATE_SYNC_IMAGE) $(PUBLIC_API_IMAGE) $(API_SERVER_IMAGE) $(OBSERVABILITY_DASHBOARD_IMAGE); do \
+	`@for` img in $(BACKEND_IMAGE) $(FRONTEND_IMAGE) $(OPERATOR_IMAGE) $(RUNNER_IMAGE) $(STATE_SYNC_IMAGE) $(PUBLIC_API_IMAGE) $(API_SERVER_IMAGE) $(OBSERVABILITY_DASHBOARD_IMAGE) $(GITHUB_MCP_IMAGE) $(JIRA_MCP_IMAGE) $(K8S_MCP_IMAGE) $(GOOGLE_MCP_IMAGE); do \
🧰 Tools
🪛 checkmake (0.3.2)

[warning] 228-228: Target "build-credential-sidecars" should be declared PHONY.

(phonydeclared)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 228 - 254, The new credential sidecar targets
(build-credential-github, build-credential-jira, build-credential-k8s,
build-credential-google) are not wired into the main flows; update the primary
meta targets build-all, push-all and the _kind-load-images target to include
these sidecar targets (or include a sidecar variable list) so that running make
build-all, make push-all, or make _kind-load-images (and make kind-up
LOCAL_IMAGES=true) will build/push/load the credential sidecars; reference the
targets by name (build-credential-github, build-credential-jira,
build-credential-k8s, build-credential-google) when adding them as dependencies
or appending them to the appropriate image lists used by build-all, push-all and
_kind-load-images.

build-cli: ## Build acpctl CLI binary
@echo "$(COLOR_BLUE)▶$(COLOR_RESET) Building acpctl CLI..."
@cd components/ambient-cli && make build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4963,7 +4963,6 @@ components:
type: string
required:
- name
- project_id
- provider
type: object
example:
Expand All @@ -4975,7 +4974,6 @@ components:
token: token
labels: labels
updated_at: 2000-01-23T04:56:07.000+00:00
project_id: project_id
provider: github
name: name
id: id
Expand Down
35 changes: 21 additions & 14 deletions components/ambient-api-server/pkg/api/openapi/model_credential.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ func migration() *gormigrate.Migration {
type Project struct {
db.Model
Name string `gorm:"uniqueIndex;not null"`
DisplayName *string
Description *string
Labels *string
Annotations *string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func migration() *gormigrate.Migration {

func typedFKMigration() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202505130001",
ID: "202603100139",
Migrate: func(tx *gorm.DB) error {
// Drop the old unique index that depends on scope_id before altering columns
if err := tx.Exec(`DROP INDEX IF EXISTS idx_binding_lookup`).Error; err != nil {
Expand Down
17 changes: 17 additions & 0 deletions components/ambient-cli/cmd/acpctl/create/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ var createArgs struct {
bindAgentID string
bindSessionID string
bindCredID string
scopeID string
}

func init() {
Expand All @@ -80,6 +81,7 @@ func init() {
Cmd.Flags().StringVar(&createArgs.bindAgentID, "agent-id-fk", "", "Agent FK for role-binding")
Cmd.Flags().StringVar(&createArgs.bindSessionID, "session-id-fk", "", "Session FK for role-binding")
Cmd.Flags().StringVar(&createArgs.bindCredID, "credential-id-fk", "", "Credential FK for role-binding")
Cmd.Flags().StringVar(&createArgs.scopeID, "scope-id", "", "Scope target ID for role-binding (shorthand for --{scope}-id-fk)")
}

func run(cmd *cobra.Command, cmdArgs []string) error {
Expand Down Expand Up @@ -299,6 +301,21 @@ func createRoleBinding(cmd *cobra.Command, ctx context.Context, client *sdkclien
return fmt.Errorf("--scope is required")
}

if createArgs.scopeID != "" {
switch createArgs.scope {
case "project":
createArgs.bindProjectID = createArgs.scopeID
case "agent":
createArgs.bindAgentID = createArgs.scopeID
case "session":
createArgs.bindSessionID = createArgs.scopeID
case "credential":
createArgs.bindCredID = createArgs.scopeID
default:
return fmt.Errorf("--scope-id not supported for scope %q; use the explicit FK flag", createArgs.scope)
}
}

builder := sdktypes.NewRoleBindingBuilder().
RoleID(createArgs.roleID).
Scope(createArgs.scope)
Expand Down
29 changes: 29 additions & 0 deletions components/ambient-cli/cmd/acpctl/create/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,35 @@ func TestCreateRoleBinding_Success(t *testing.T) {
}
}

func TestCreateRoleBinding_ScopeID(t *testing.T) {
srv := testhelper.NewServer(t)
srv.Handle("/api/ambient/v1/role_bindings", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Errorf("expected POST, got %s", r.Method)
}
credID := "cred-1"
srv.RespondJSON(t, w, http.StatusCreated, &types.RoleBinding{
ObjectReference: types.ObjectReference{ID: "rb-scope"},
RoleID: "r-1",
Scope: "credential",
CredentialID: &credID,
})
})

testhelper.Configure(t, srv.URL)
result := testhelper.Run(t, Cmd, "role-binding",
"--role-id", "r-1",
"--scope", "credential",
"--scope-id", "cred-1",
)
if result.Err != nil {
t.Fatalf("unexpected error: %v\nstdout: %s\nstderr: %s", result.Err, result.Stdout, result.Stderr)
}
if !strings.Contains(result.Stdout, "role-binding/rb-scope") {
t.Errorf("expected 'role-binding/rb-scope created', got: %s", result.Stdout)
}
}

func TestCreateRoleBinding_MissingScope(t *testing.T) {
srv := testhelper.NewServer(t)
testhelper.Configure(t, srv.URL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func runKubeMode(ctx context.Context, cfg *config.ControlPlaneConfig) error {
RunnerImageNamespace: cfg.RunnerImageNamespace,
MCPImage: cfg.MCPImage,
MCPAPIServerURL: cfg.MCPAPIServerURL,
GitHubMCPImage: cfg.GitHubMCPImage,
JiraMCPImage: cfg.JiraMCPImage,
K8sMCPImage: cfg.K8sMCPImage,
GoogleMCPImage: cfg.GoogleMCPImage,
RunnerLogLevel: cfg.RunnerLogLevel,
CPRuntimeNamespace: cfg.CPRuntimeNamespace,
CPTokenURL: cfg.CPTokenURL,
Expand Down
8 changes: 8 additions & 0 deletions components/ambient-control-plane/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ type ControlPlaneConfig struct {
RunnerImageNamespace string
MCPImage string
MCPAPIServerURL string
GitHubMCPImage string
JiraMCPImage string
K8sMCPImage string
GoogleMCPImage string
RunnerLogLevel string
ProjectKubeTokenFile string
CPTokenListenAddr string
Expand Down Expand Up @@ -74,6 +78,10 @@ func Load() (*ControlPlaneConfig, error) {
RunnerImageNamespace: os.Getenv("RUNNER_IMAGE_NAMESPACE"),
MCPImage: os.Getenv("MCP_IMAGE"),
MCPAPIServerURL: envOrDefault("MCP_API_SERVER_URL", ""),
GitHubMCPImage: os.Getenv("GITHUB_MCP_IMAGE"),
JiraMCPImage: os.Getenv("JIRA_MCP_IMAGE"),
K8sMCPImage: os.Getenv("K8S_MCP_IMAGE"),
GoogleMCPImage: os.Getenv("GOOGLE_MCP_IMAGE"),
RunnerLogLevel: envOrDefault("RUNNER_LOG_LEVEL", "info"),
ProjectKubeTokenFile: os.Getenv("PROJECT_KUBE_TOKEN_FILE"),
CPTokenListenAddr: envOrDefault("CP_TOKEN_LISTEN_ADDR", ":8080"),
Expand Down
Loading
Loading