diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 709912de1ceaae14c71533072afdd45e372b820b..6b8566e9a94d8818ad31a76e0470f36fc152976c 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -175,17 +175,17 @@ jobs:
           /tmp/flux delete source git podinfo --silent
       - name: flux oci artifacts
         run: |
-          /tmp/flux push artifact localhost:5000/fluxcd/flux:${{ github.sha }} \
+          /tmp/flux push artifact oci://localhost:5000/fluxcd/flux:${{ github.sha }} \
             --path="./manifests" \
             --source="${{ github.repositoryUrl }}" \
             --revision="${{ github.ref }}/${{ github.sha }}"
-          /tmp/flux tag artifact localhost:5000/fluxcd/flux:${{ github.sha }} \
+          /tmp/flux tag artifact oci://localhost:5000/fluxcd/flux:${{ github.sha }} \
             --tag latest
-          /tmp/flux list artifacts localhost:5000/fluxcd/flux
+          /tmp/flux list artifacts oci://localhost:5000/fluxcd/flux
       - name: flux oci repositories
         run: |
           /tmp/flux create source oci podinfo-oci \
-            --url ghcr.io/stefanprodan/manifests/podinfo \
+            --url oci://ghcr.io/stefanprodan/manifests/podinfo \
             --tag-semver 6.1.x \
             --interval 10m
           /tmp/flux create kustomization podinfo-oci \
diff --git a/cmd/flux/create_source_oci.go b/cmd/flux/create_source_oci.go
index a97c64fb12d3c82017108ced35f54cb727ccecbf..dd2b4fbfec23fcb592ab95f19b53a1383e6977d9 100644
--- a/cmd/flux/create_source_oci.go
+++ b/cmd/flux/create_source_oci.go
@@ -42,7 +42,7 @@ var createSourceOCIRepositoryCmd = &cobra.Command{
 	Long:  `The create source oci command generates an OCIRepository resource and waits for it to be ready.`,
 	Example: `  # Create an OCIRepository for a public container image
   flux create source oci podinfo \
-    --url=ghcr.io/stefanprodan/manifests/podinfo \
+    --url=oci://ghcr.io/stefanprodan/manifests/podinfo \
     --tag=6.1.6 \
     --interval=10m
 `,
@@ -67,7 +67,7 @@ func init() {
 	createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.semver, "tag-semver", "", "the OCI artifact tag semver range")
 	createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.digest, "digest", "", "the OCI artifact digest")
 	createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.secretRef, "secret-ref", "", "the name of the Kubernetes image pull secret (type 'kubernetes.io/dockerconfigjson')")
-	createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.secretRef, "service-account", "", "the name of the Kubernetes service account that refers to an image pull secret")
+	createSourceOCIRepositoryCmd.Flags().StringVar(&sourceOCIRepositoryArgs.serviceAccount, "service-account", "", "the name of the Kubernetes service account that refers to an image pull secret")
 	createSourceOCIRepositoryCmd.Flags().StringSliceVar(&sourceOCIRepositoryArgs.ignorePaths, "ignore-paths", nil, "set paths to ignore resources (can specify multiple paths with commas: path1,path2)")
 
 	createSourceCmd.AddCommand(createSourceOCIRepositoryCmd)
diff --git a/cmd/flux/create_source_oci_test.go b/cmd/flux/create_source_oci_test.go
index 027c17899f35cc7f7ed16c8fd75026586b71a3b8..04be9cb136e8b7e2d8639d12078661ed5183c4fe 100644
--- a/cmd/flux/create_source_oci_test.go
+++ b/cmd/flux/create_source_oci_test.go
@@ -38,12 +38,12 @@ func TestCreateSourceOCI(t *testing.T) {
 		},
 		{
 			name:       "export manifest",
-			args:       "create source oci podinfo --url=ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m --export",
+			args:       "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m --export",
 			assertFunc: assertGoldenFile("./testdata/oci/export.golden"),
 		},
 		{
 			name:       "export manifest with secret",
-			args:       "create source oci podinfo --url=ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m --secret-ref=creds --export",
+			args:       "create source oci podinfo --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m --secret-ref=creds --export",
 			assertFunc: assertGoldenFile("./testdata/oci/export_with_secret.golden"),
 		},
 	}
diff --git a/cmd/flux/list_artifact.go b/cmd/flux/list_artifact.go
index a53e4f9975d10edb825de31e5661fb711158ff6c..e499fc7341f6ffa4d4c9c9a4288a0b1211fe5a69 100644
--- a/cmd/flux/list_artifact.go
+++ b/cmd/flux/list_artifact.go
@@ -30,7 +30,7 @@ var listArtifactsCmd = &cobra.Command{
 	Long: `The list command fetches the tags and their metadata from a remote OCI repository.
 The list command uses the credentials from '~/.docker/config.json'.`,
 	Example: `# list the artifacts stored in an OCI repository
-flux list artifact ghcr.io/org/manifests/app
+flux list artifact oci://ghcr.io/org/manifests/app
 `,
 	RunE: listArtifactsCmdRun,
 }
@@ -41,13 +41,18 @@ func init() {
 
 func listArtifactsCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
-		return fmt.Errorf("artifact repository is required")
+		return fmt.Errorf("artifact repository URL is required")
 	}
-	url := args[0]
+	ociURL := args[0]
 
 	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
 	defer cancel()
 
+	url, err := oci.ParseArtifactURL(ociURL)
+	if err != nil {
+		return err
+	}
+
 	metas, err := oci.List(ctx, url)
 	if err != nil {
 		return err
diff --git a/cmd/flux/main_test.go b/cmd/flux/main_test.go
index 59568dee79fd360e5d4c06c666f244b17c6ec632..2adf47159d931ed7f1be7f3c33659bd807bd87b4 100644
--- a/cmd/flux/main_test.go
+++ b/cmd/flux/main_test.go
@@ -387,6 +387,9 @@ func resetCmdArgs() {
 	createArgs = createFlags{}
 	getArgs = GetFlags{}
 	sourceHelmArgs = sourceHelmFlags{}
+	sourceOCIRepositoryArgs = sourceOCIRepositoryFlags{}
+	sourceGitArgs = sourceGitFlags{}
+	sourceBucketArgs = sourceBucketFlags{}
 	secretGitArgs = NewSecretGitFlags()
 	*kubeconfigArgs.Namespace = rootArgs.defaults.Namespace
 }
diff --git a/cmd/flux/pull_artifact.go b/cmd/flux/pull_artifact.go
index 37560f68a447d7e29fa9821879ece048a5ea7ae9..382cdc6954cfe691d301f8755a502ca23fe9a939 100644
--- a/cmd/flux/pull_artifact.go
+++ b/cmd/flux/pull_artifact.go
@@ -32,7 +32,7 @@ var pullArtifactCmd = &cobra.Command{
 	Long: `The pull artifact command downloads and extracts the OCI artifact content to the given path.
 The pull command uses the credentials from '~/.docker/config.json'.`,
 	Example: `# Pull an OCI artifact created by flux from GHCR
-flux pull artifact ghcr.io/org/manifests/app:v0.0.1 --output ./path/to/local/manifests
+flux pull artifact oci://ghcr.io/org/manifests/app:v0.0.1 --output ./path/to/local/manifests
 `,
 	RunE: pullArtifactCmdRun,
 }
@@ -50,9 +50,9 @@ func init() {
 
 func pullArtifactCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
-		return fmt.Errorf("artifact name is required")
+		return fmt.Errorf("artifact URL is required")
 	}
-	url := args[0]
+	ociURL := args[0]
 
 	if pullArtifactArgs.output == "" {
 		return fmt.Errorf("invalid output path %s", pullArtifactArgs.output)
@@ -62,6 +62,11 @@ func pullArtifactCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("invalid output path %s", pullArtifactArgs.output)
 	}
 
+	url, err := oci.ParseArtifactURL(ociURL)
+	if err != nil {
+		return err
+	}
+
 	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
 	defer cancel()
 
diff --git a/cmd/flux/push_artifact.go b/cmd/flux/push_artifact.go
index 813dbb46e1a79eb2877c645692284db23e9aa5c4..49f6120287cdfe4a9bc8fd7834863f4238943784 100644
--- a/cmd/flux/push_artifact.go
+++ b/cmd/flux/push_artifact.go
@@ -32,7 +32,7 @@ var pushArtifactCmd = &cobra.Command{
 	Long: `The push artifact command creates a tarball from the given directory and uploads the artifact to a OCI repository.
 The push command uses the credentials from '~/.docker/config.json'.`,
 	Example: `# Push the local manifests to GHCR
-flux push artifact  ghcr.io/org/manifests/app:v0.0.1 \
+flux push artifact oci://ghcr.io/org/manifests/app:v0.0.1 \
 	--path="./path/to/local/manifests" \
 	--source="$(git config --get remote.origin.url)" \
 	--revision="$(git branch --show-current)/$(git rev-parse HEAD)"
@@ -57,9 +57,9 @@ func init() {
 
 func pushArtifactCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
-		return fmt.Errorf("artifact name is required")
+		return fmt.Errorf("artifact URL is required")
 	}
-	url := args[0]
+	ociURL := args[0]
 
 	if pushArtifactArgs.source == "" {
 		return fmt.Errorf("--source is required")
@@ -73,6 +73,11 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error {
 		return fmt.Errorf("invalid path %q", pushArtifactArgs.path)
 	}
 
+	url, err := oci.ParseArtifactURL(ociURL)
+	if err != nil {
+		return err
+	}
+
 	if fs, err := os.Stat(pushArtifactArgs.path); err != nil || !fs.IsDir() {
 		return fmt.Errorf("invalid path %q", pushArtifactArgs.path)
 	}
diff --git a/cmd/flux/source_oci_test.go b/cmd/flux/source_oci_test.go
index 568ac73ee6f9e36717c1b9d47206831e9f516f3c..c0f8125cbda82782c7c7385d0f1e29fb711a0f7c 100644
--- a/cmd/flux/source_oci_test.go
+++ b/cmd/flux/source_oci_test.go
@@ -29,7 +29,7 @@ func TestSourceOCI(t *testing.T) {
 		goldenFile string
 	}{
 		{
-			"create source oci thrfg --url=ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m",
+			"create source oci thrfg --url=oci://ghcr.io/stefanprodan/manifests/podinfo --tag=6.1.6 --interval 10m",
 			"testdata/oci/create_source_oci.golden",
 		},
 		{
diff --git a/cmd/flux/tag_artifact.go b/cmd/flux/tag_artifact.go
index be0a6387d76286a4f24844480fcc859e2128bc4e..2004cebc1aaf0f7ebd48c1ceeb70a2f72a191557 100644
--- a/cmd/flux/tag_artifact.go
+++ b/cmd/flux/tag_artifact.go
@@ -29,7 +29,7 @@ var tagArtifactCmd = &cobra.Command{
 	Long: `The tag artifact command creates tags for the given OCI artifact.
 The tag command uses the credentials from '~/.docker/config.json'.`,
 	Example: `# Tag an artifact version as latest
-flux tag artifact ghcr.io/org/manifests/app:v0.0.1 --tag latest
+flux tag artifact oci://ghcr.io/org/manifests/app:v0.0.1 --tag latest
 `,
 	RunE: tagArtifactCmdRun,
 }
@@ -49,12 +49,17 @@ func tagArtifactCmdRun(cmd *cobra.Command, args []string) error {
 	if len(args) < 1 {
 		return fmt.Errorf("artifact name is required")
 	}
-	url := args[0]
+	ociURL := args[0]
 
 	if len(tagArtifactArgs.tags) < 1 {
 		return fmt.Errorf("--tag is required")
 	}
 
+	url, err := oci.ParseArtifactURL(ociURL)
+	if err != nil {
+		return err
+	}
+
 	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
 	defer cancel()
 
diff --git a/cmd/flux/testdata/oci/export.golden b/cmd/flux/testdata/oci/export.golden
index 82d5fa19b5536947d9543988f935afd41f4100ca..b9339d73e01d9ba3a8400c2e9dafca016c1d8736 100644
--- a/cmd/flux/testdata/oci/export.golden
+++ b/cmd/flux/testdata/oci/export.golden
@@ -8,5 +8,5 @@ spec:
   interval: 10m0s
   ref:
     tag: 6.1.6
-  url: ghcr.io/stefanprodan/manifests/podinfo
+  url: oci://ghcr.io/stefanprodan/manifests/podinfo
 
diff --git a/cmd/flux/testdata/oci/export_with_secret.golden b/cmd/flux/testdata/oci/export_with_secret.golden
index 79fd98a5c92187f6ff79982ea9c57763fa20e04f..385f7707113ce2b260ffab8f9c845ff39f01ce38 100644
--- a/cmd/flux/testdata/oci/export_with_secret.golden
+++ b/cmd/flux/testdata/oci/export_with_secret.golden
@@ -10,5 +10,5 @@ spec:
     tag: 6.1.6
   secretRef:
     name: creds
-  url: ghcr.io/stefanprodan/manifests/podinfo
+  url: oci://ghcr.io/stefanprodan/manifests/podinfo
 
diff --git a/internal/oci/url.go b/internal/oci/url.go
new file mode 100644
index 0000000000000000000000000000000000000000..38dafb1f506e02f23cac4e88688fe4e388a7688e
--- /dev/null
+++ b/internal/oci/url.go
@@ -0,0 +1,54 @@
+/*
+Copyright 2022 The Flux authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package oci
+
+import (
+	"fmt"
+	"strings"
+
+	sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
+	"github.com/google/go-containerregistry/pkg/name"
+)
+
+// ParseArtifactURL validates the OCI URL and returns the address of the artifact.
+func ParseArtifactURL(ociURL string) (string, error) {
+	if !strings.HasPrefix(ociURL, sourcev1.OCIRepositoryPrefix) {
+		return "", fmt.Errorf("URL must be in format 'oci://<domain>/<org>/<repo>'")
+	}
+
+	url := strings.TrimPrefix(ociURL, sourcev1.OCIRepositoryPrefix)
+	if _, err := name.ParseReference(url); err != nil {
+		return "", fmt.Errorf("'%s' invalid URL: %w", ociURL, err)
+	}
+
+	return url, nil
+}
+
+// ParseRepositoryURL validates the OCI URL and returns the address of the artifact repository.
+func ParseRepositoryURL(ociURL string) (string, error) {
+	if !strings.HasPrefix(ociURL, sourcev1.OCIRepositoryPrefix) {
+		return "", fmt.Errorf("URL must be in format 'oci://<domain>/<org>/<repo>'")
+	}
+
+	url := strings.TrimPrefix(ociURL, sourcev1.OCIRepositoryPrefix)
+	ref, err := name.ParseReference(url)
+	if err != nil {
+		return "", fmt.Errorf("'%s' invalid URL: %w", ociURL, err)
+	}
+
+	return ref.Context().Name(), nil
+}
diff --git a/manifests/bases/source-controller/kustomization.yaml b/manifests/bases/source-controller/kustomization.yaml
index 9d2e44e026d559807762575c33f9506393369932..f268590cfa6f3fae3e53f8dd635e36c4053a03fa 100644
--- a/manifests/bases/source-controller/kustomization.yaml
+++ b/manifests/bases/source-controller/kustomization.yaml
@@ -15,4 +15,4 @@ patchesJson6902:
 # TODO: remove the hardcoded image when OCIRepository is released
 images:
   - name: fluxcd/source-controller
-    newTag: oci-8509ac03
+    newTag: oci-ba5f5353