diff --git a/aws/efs/README.md b/aws/efs/README.md
index 51db96e52526224da4b60efde09344c4f3138cf8..ddf39e744ec8c2b16a90a6083dccd7ba14112463 100644
--- a/aws/efs/README.md
+++ b/aws/efs/README.md
@@ -181,11 +181,13 @@ provisioner: example.com/aws-efs
 parameters:
   gidMin: "40000"
   gidMax: "50000"
+  gidAllocate: "true"
 ```
 
 ### Parameters
 
-* `gidMin` + `gidMax` : The minimum and maximum value of GID range for the storage class. A unique value (GID) in this range ( gidMin-gidMax ) will be used for dynamically provisioned volumes. These are optional values. If not specified, the volume will be provisioned with a value between 2000-2147483647 which are defaults for gidMin and gidMax respectively.
+* `gidMin` + `gidMax` : A unique value (GID) in this range (`gidMin`-`gidMax`) will be allocated for each dynamically provisioned volume. Each volume will be secured to its allocated GID. Any pod that consumes the claim will be able to read/write the volume because the pod will automatically receive the volume's allocated GID as a supplemental group, but non-pod mounters outside the system will not have read/write access unless they have the GID or root privileges. See [here](https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#access-control) and [here](https://docs.openshift.com/container-platform/3.6/install_config/persistent_storage/pod_security_context.html#supplemental-groups) for more information. Default to `"2000"` and `"2147483647"`.
+* `gidAllocate` : Whether to allocate GIDs to volumes according to the above scheme at all. If `"false"`, dynamically provisioned volumes will not be allocated GIDs, `gidMin` and `gidMax` will be ignored, and anyone will be able to read/write volumes. Defaults to `"true"`.
 
 Once you have finished configuring the class to have the name you chose when deploying the provisioner and the parameters you want, create it.
 
@@ -203,7 +205,6 @@ $ kubectl get pv
 NAME                                       CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM         REASON    AGE
 pvc-557b4436-ed73-11e6-84b3-06a700dda5f5   1Mi        RWX           Delete          Bound     default/efs             2s
 ```
-Note: any pod that consumes the claim will be able to read/write to the volume. This is because the volumes are provisioned with a GID (from the default range or according to `gidMin` + `gidMax`) and any pod that mounts the volume via the claim automatically gets the GID as a supplemental group.
 
 ---
 ##### Optional: AWS credentials secret
diff --git a/aws/efs/cmd/efs-provisioner/efs-provisioner.go b/aws/efs/cmd/efs-provisioner/efs-provisioner.go
index e2aaa9de0f57d947265bf79e63cb1401e7fd4e13..68f4296cf0bc4f4bf3ba6ec6e201f781bc65a457 100644
--- a/aws/efs/cmd/efs-provisioner/efs-provisioner.go
+++ b/aws/efs/cmd/efs-provisioner/efs-provisioner.go
@@ -124,9 +124,29 @@ func (p *efsProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis
 		return nil, fmt.Errorf("claim.Spec.Selector is not supported")
 	}
 
-	gid, err := p.allocator.AllocateNext(options)
-	if err != nil {
-		return nil, err
+	gidAllocate := true
+	var err error
+	for k, v := range options.Parameters {
+		switch strings.ToLower(k) {
+		case "gidmin":
+		// Let allocator handle
+		case "gidmax":
+		// Let allocator handle
+		case "gidallocate":
+			gidAllocate, err = strconv.ParseBool(v)
+			if err != nil {
+				return nil, fmt.Errorf("invalid value %s for parameter %s: %v", v, k, err)
+			}
+		}
+	}
+
+	var gid *int
+	if gidAllocate {
+		allocate, err := p.allocator.AllocateNext(options)
+		if err != nil {
+			return nil, err
+		}
+		gid = &allocate
 	}
 
 	err = p.createVolume(p.getLocalPath(options), gid)
@@ -137,9 +157,6 @@ func (p *efsProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis
 	pv := &v1.PersistentVolume{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: options.PVName,
-			Annotations: map[string]string{
-				gidallocator.VolumeGidAnnotationKey: strconv.FormatInt(int64(gid), 10),
-			},
 		},
 		Spec: v1.PersistentVolumeSpec{
 			PersistentVolumeReclaimPolicy: options.PersistentVolumeReclaimPolicy,
@@ -156,12 +173,20 @@ func (p *efsProvisioner) Provision(options controller.VolumeOptions) (*v1.Persis
 			},
 		},
 	}
+	if gidAllocate {
+		pv.ObjectMeta.Annotations = map[string]string{
+			gidallocator.VolumeGidAnnotationKey: strconv.FormatInt(int64(*gid), 10),
+		}
+	}
 
 	return pv, nil
 }
 
-func (p *efsProvisioner) createVolume(path string, gid int) error {
-	perm := os.FileMode(0771 | os.ModeSetgid)
+func (p *efsProvisioner) createVolume(path string, gid *int) error {
+	perm := os.FileMode(0777)
+	if gid != nil {
+		perm = os.FileMode(0771 | os.ModeSetgid)
+	}
 
 	if err := os.MkdirAll(path, perm); err != nil {
 		return err
@@ -173,11 +198,13 @@ func (p *efsProvisioner) createVolume(path string, gid int) error {
 		return err
 	}
 
-	cmd := exec.Command("chgrp", strconv.Itoa(gid), path)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		os.RemoveAll(path)
-		return fmt.Errorf("chgrp failed with error: %v, output: %s", err, out)
+	if gid != nil {
+		cmd := exec.Command("chgrp", strconv.Itoa(*gid), path)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			os.RemoveAll(path)
+			return fmt.Errorf("chgrp failed with error: %v, output: %s", err, out)
+		}
 	}
 
 	return nil