Skip to content

[FEATURE] Private skill and plugin sources in the v1alpha3 API #2815

Open

Description

@QuentinBisson

📋 Prerequisites

📝 Feature Summary

Support private git, OCI and S3 artifact sources for AgentTemplate skills and plugins, as v1alpha2 does today.

❓ Problem Statement / Motivation

  • The released v1alpha2 API supports private skill sources. skills.gitAuthSecretRef takes a Secret with a token key for HTTPS or ssh-privatekey for SSH, skills.imagePullSecrets covers OCI, and S3 reads AWS credentials from the init container environment (go/api/v1alpha2/agent_types.go:140-166, as of v0.10.1).
  • The v1alpha3 API on main has no equivalent. ArtifactSource carries only oci, git, bucket and path (go/api/v1alpha3/agenttemplate_types.go:161), and the runtime fetches with no credential at all (go/core/pkg/agentplugins/materialize.go:174-227). Every private source fails.
  • The implementation still exists and has no caller. skillsinit.Run, SetupGitAuth and MergeDockerConfigs were orphaned by 059c01b (refactor: simplify runtime images and add lifecycle e2e #2498), which deleted the only caller. feat: load Agent Plugins in Go runtime #2500 re-used the fetch primitives and not the auth setup, and neither commit message mentions it.
  • Anyone moving from v1alpha2 to v1alpha3 with a private skill repository loses a working feature. No released tag contains 059c01b, so this can be settled before v1alpha3 ships.
  • The only workaround is a long-lived token in harness.spec.env. That is resolved to a plaintext literal before the Substrate boundary, because ate-api EnvVar accepts literals only, and it is then readable by every process in the sandbox.

💡 Proposed Solution

I have a fuller design worked out, including how the content is packaged, how the revision digest stays free of credential material, and how rotation behaves. I left it out here to keep the discussion on the requirement first. Happy to write it up if the direction is agreeable.

🔄 Alternatives Considered

  • Restore the v1alpha2 behaviour by reviving SetupGitAuth and mounting the credential into the runtime. Smallest change, but the credential then sits inside a sandbox that runs model-generated code.
  • Substrate egress credential injection. It cannot sign AWS SigV4, so S3 stays out of reach, and the hostname rules cannot express the OCI token exchange.
  • A short-lived credential fetched by the runtime. The sandboxed process cannot authenticate today, since MintJWT requires authenticating as the pod that runs the actor and there is no per-actor service account.
  • Bake skills into the harness image. Works today, but it couples skill selection to the image lifecycle.

🎯 Affected Service(s)

Multiple services / System-wide

📚 Additional Context

Related: #2604, a network-backed source blocks readiness. #2608 and #2646 report bugs in the skillsinit paths that no longer have a caller on main, which is the same regression seen from the released side.

🙋 Are you willing to contribute?

  • I am willing to submit a PR for this feature

Activity

  1. the-mentor commented on Sep 15, 2026

    @the-mentor
    Contributor

    I also think supporting native marketplaces and plugins are a must

    Since a lot of orgs created marketplaces to distribute their plugins etc

  2. QuentinBisson commented on Sep 29, 2026

    @QuentinBisson
    ContributorAuthor

    Following up with the fuller design I mentioned, since v1alpha3 is getting close.

    One field for all three source types, next to oci / git / bucket:

      source:
        git:
          url: https://github.com/acme/private-skills
          commit: <sha>
        secretRef:
          name: skills-auth
    

    The Secret is in the same namespace and uses the standard type for its source: kubernetes.io/basic-auth for git, kubernetes.io/dockerconfigjson for OCI, and an access key plus secret key for S3. This maps directly onto v1alpha2's gitAuthSecretRef and imagePullSecrets.

    The controller fetches the source using the Secret, packages the result as a digest-pinned image, and pushes it to a registry the platform configures. The actor mounts it read-only through a Substrate image volume. The sandbox never sees the credential and needs no egress to the source, which also takes the startup fetch out of readiness (#2604).

    This is blocked by agent-substrate/substrate#917 though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions