Create Repositories and Xray Policies with Crossplane

Create Docker repositories, a permission, a cleanup policy, and Xray policies with the JFrog Crossplane providers.

Use these Crossplane recipes to create repositories and Xray policies in the JFrog Platform. Each recipe is a set of manifests that combines the JFrog Crossplane providers.

  • Recipe 3 creates a local, a remote, and a virtual Docker repository, a permission, and a cleanup policy.
  • Recipe 4 creates an Xray security policy, a license policy, a watch, and a vulnerabilities report.

Prerequisites

📘

Note

The manifests on this page omit providerConfigRef for brevity. Every managed resource also needs providerConfigRef: {kind: ClusterProviderConfig, name: jfrog} under spec. Add it to each managed resource before you apply, or name your configurations default.

Recipe 3: Repositories, Permission, and Cleanup

Step 1: Create the Recipe 3 Manifests

Save the following manifests to a directory:

apiVersion: repository.artifactory.m.crossplane.io/v1alpha1
kind: LocalDockerV2Repository
metadata: {name: payments-docker-local, namespace: team-payments}
spec:
  forProvider: {projectKey: payments, projectEnvironments: [DEV], xrayIndex: true, maxUniqueTags: 25}
---
apiVersion: repository.artifactory.m.crossplane.io/v1alpha1
kind: RemoteDockerRepository
metadata: {name: payments-dockerhub-remote, namespace: team-payments}
spec:
  forProvider:
    url: https://registry-1.docker.io/
    enableTokenAuthentication: true
    projectKey: payments
    projectEnvironments: [DEV]
    xrayIndex: true
---
apiVersion: repository.artifactory.m.crossplane.io/v1alpha1
kind: VirtualDockerRepository
metadata: {name: payments-docker, namespace: team-payments}
spec:
  forProvider:
    repositories: [payments-docker-local, payments-dockerhub-remote]
    defaultDeploymentRepo: payments-docker-local
    projectKey: payments
    projectEnvironments: [DEV]
---
apiVersion: access.platform.m.crossplane.io/v1alpha1
kind: Permission
metadata: {name: payments-repos, namespace: team-payments}
spec:
  forProvider:
    artifact:
      actions:
        groups: [{name: payments-developers, permissions: [READ, WRITE, ANNOTATE]}]
      targets:
        - {name: payments-docker-local, includePatterns: ['**']}
        - {name: payments-docker, includePatterns: ['**']}
---
apiVersion: configuration.artifactory.m.crossplane.io/v1alpha1
kind: PackageCleanupPolicy
metadata: {name: payments-docker-cleanup, namespace: team-payments}
spec:
  forProvider:
    enabled: true
    cronExpression: "0 0 3 ? * SUN *"
    durationInMinutes: 60
    searchCriteria:
      createdBeforeInDays: 90
      lastDownloadedBeforeInDays: 60
      includedProjects: [payments]
      includedPackages: ['**']
      packageTypes: [docker]
      repos: [payments-docker-local]

About these manifests:

  • Every member in the virtual repository repositories list must exist.
  • The order of the members determines resolution.
  • defaultDeploymentRepo enables deploys through the virtual URL.
  • Every principal and repository that the Permission names must exist.

Step 2: Apply the Recipe 3 Manifests

Run the following command:

kubectl apply -R -f <dir>/

The same pattern works for every package type, for example LocalNPMRepository, RemoteNPMRepository with url: https://registry.npmjs.org/, and VirtualNPMRepository.

Recipe 4: Xray Policy, Watch, and Report

Step 1: Create the Recipe 4 Manifests

Save the following manifests to a directory:

apiVersion: policy.xray.m.crossplane.io/v1alpha1
kind: SecurityPolicy
metadata: {name: payments-block-high, namespace: team-payments}
spec:
  forProvider:
    type: security
    projectKey: payments
    rule:
      - name: block-high-and-above
        priority: 1
        criteria: [{minSeverity: High, fixVersionDependant: false}]
        actions:
          - failBuild: true
            notifyWatchRecipients: true
            blockDownload: [{active: true, unscanned: false}]
---
apiVersion: policy.xray.m.crossplane.io/v1alpha1
kind: LicensePolicy
metadata: {name: payments-no-gpl, namespace: team-payments}
spec:
  forProvider:
    type: license
    projectKey: payments
    rule:
      - name: ban-gpl
        priority: 1
        criteria:
          - bannedLicenses: ["GPL-3.0", "AGPL-3.0"]
        actions:
          - failBuild: true
            notifyWatchRecipients: true
            blockDownload: [{active: true, unscanned: false}]
---
apiVersion: watch.xray.m.crossplane.io/v1alpha1
kind: Watch
metadata: {name: payments-watch, namespace: team-payments}
spec:
  forProvider:
    active: true
    projectKey: payments
    assignedPolicy:
      - {nameRef: {name: payments-block-high}, type: security}
      - {name: payments-no-gpl, type: license}          # LicensePolicy: literal name
    watchResource:
      - {type: repository, name: payments-docker-local}
      - {type: repository, name: payments-dockerhub-remote, repoType: remote}
---
apiVersion: report.xray.m.crossplane.io/v1alpha1
kind: VulnerabilitiesReport
metadata: {name: payments-weekly-cves, namespace: team-payments}
spec:
  forProvider:
    name: payments-weekly-cves
    cronSchedule: "0 9 * * MON"
    cronScheduleTimezone: America/Los_Angeles
    resources: [{repository: [{name: payments-docker-local, includePathPatterns: ['**']}]}]
    filters: [{cvssScore: [{minScore: 7, maxScore: 10}]}]

About these manifests:

  • The Watch assigns payments-no-gpl by literal name. assignedPolicy[].nameRef can only target SecurityPolicy. License and operational-risk policies must be referenced by literal name, and that policy must exist in Xray. Step 1 of this recipe creates it. If it is missing, create fails with policy <name> doesn't exist.
  • In watchResource, set repoType: remote for remote repositories. The watched repositories in Recipe 3 set xrayIndex: true.
  • Changing a policy rule updates it in place. Reports can't be updated.

Step 2: Apply the Recipe 4 Manifests

Run the following command. It applies every manifest in the directory, including the security policy, the license policy, the watch, and the report.

kubectl apply -R -f <dir>/

Check the Result

List every managed resource:

kubectl get managed -A

To check one Kind, run the following commands. Use the fully-qualified Kind name, for example watches.watch.xray.m.crossplane.io.

kubectl get <fq-kind> -n team-payments
kubectl describe <fq-kind>/<name> -n team-payments
  • The first command shows the SYNCED, READY, and EXTERNAL-NAME columns.
  • The second command shows conditions and events.

Next Steps


Did this page help you?