diff --git a/client/client.go b/client/client.go
index 6dd8d0d..3f8a551 100644
--- a/client/client.go
+++ b/client/client.go
@@ -64,6 +64,15 @@ type PortainerClient interface {
 	// Proxy proxies a request to /endpoint/{id}/docker and returns its result
 	Proxy(endpointID portainer.EndpointID, req *http.Request) (resp *http.Response, err error)
 
+	// ResourceControlCreate creates a resource control
+	ResourceControlCreate(options ResourceControlCreateOptions) (resourceControl portainer.ResourceControl, err error)
+
+	// ResourceControlUpdate updates a resource control
+	ResourceControlUpdate(options ResourceControlUpdateOptions) (resourceControl portainer.ResourceControl, err error)
+
+	// ResourceControlDelete deletes a resource control
+	ResourceControlDelete(resourceControlID portainer.ResourceControlID) (err error)
+
 	// UserList retrieves a list of users
 	UserList() (users []portainer.User, err error)
 
diff --git a/client/resourceControl_create.go b/client/resourceControl_create.go
new file mode 100644
index 0000000..0fd486b
--- /dev/null
+++ b/client/resourceControl_create.go
@@ -0,0 +1,42 @@
+package client
+
+import (
+	"fmt"
+	"net/http"
+
+	portainer "github.com/portainer/portainer/api"
+)
+
+// ResourceControlCreateOptions represents options passed to PortainerClient.ResourceControlCreate()
+type ResourceControlCreateOptions struct {
+	ResourceID     string
+	Type           ResourceType
+	Public         bool
+	Users          []portainer.UserID
+	Teams          []portainer.TeamID
+	SubResourceIDs []string
+}
+
+// ResourceControlCreateRequest represents the body of a request to POST /resource_controls
+type ResourceControlCreateRequest struct {
+	ResourceID     string
+	Type           ResourceType
+	Public         bool               `json:",omitempty"`
+	Users          []portainer.UserID `json:",omitempty"`
+	Teams          []portainer.TeamID `json:",omitempty"`
+	SubResourceIDs []string           `json:",omitempty"`
+}
+
+func (n *portainerClientImp) ResourceControlCreate(options ResourceControlCreateOptions) (resourceControl portainer.ResourceControl, err error) {
+	reqBody := ResourceControlCreateRequest{
+		ResourceID:     options.ResourceID,
+		Type:           options.Type,
+		Public:         options.Public,
+		Users:          options.Users,
+		Teams:          options.Teams,
+		SubResourceIDs: options.SubResourceIDs,
+	}
+
+	err = n.DoJSONWithToken(fmt.Sprintf("resource_controls"), http.MethodPost, http.Header{}, &reqBody, &resourceControl)
+	return
+}
diff --git a/client/resourceControl_delete.go b/client/resourceControl_delete.go
new file mode 100644
index 0000000..aa072d3
--- /dev/null
+++ b/client/resourceControl_delete.go
@@ -0,0 +1,13 @@
+package client
+
+import (
+	"fmt"
+	"net/http"
+
+	portainer "github.com/portainer/portainer/api"
+)
+
+func (n *portainerClientImp) ResourceControlDelete(resourceControlID portainer.ResourceControlID) (err error) {
+	err = n.DoJSONWithToken(fmt.Sprintf("resource_controls/%d", resourceControlID), http.MethodDelete, http.Header{}, nil, nil)
+	return
+}
diff --git a/client/resourceControl_update.go b/client/resourceControl_update.go
new file mode 100644
index 0000000..d12b722
--- /dev/null
+++ b/client/resourceControl_update.go
@@ -0,0 +1,34 @@
+package client
+
+import (
+	"fmt"
+	"net/http"
+
+	portainer "github.com/portainer/portainer/api"
+)
+
+// ResourceControlUpdateOptions represents options passed to PortainerClient.ResourceControlUpdate()
+type ResourceControlUpdateOptions struct {
+	ID     portainer.ResourceControlID
+	Public bool
+	Users  []portainer.UserID
+	Teams  []portainer.TeamID
+}
+
+// ResourceControlUpdateRequest represents the body of a request to PUT /resource_controls/{id}
+type ResourceControlUpdateRequest struct {
+	Public bool               `json:",omitempty"`
+	Users  []portainer.UserID `json:",omitempty"`
+	Teams  []portainer.TeamID `json:",omitempty"`
+}
+
+func (n *portainerClientImp) ResourceControlUpdate(options ResourceControlUpdateOptions) (resourceControl portainer.ResourceControl, err error) {
+	reqBody := ResourceControlUpdateRequest{
+		Public: options.Public,
+		Users:  options.Users,
+		Teams:  options.Teams,
+	}
+
+	err = n.DoJSONWithToken(fmt.Sprintf("resource_controls/%d", options.ID), http.MethodPut, http.Header{}, &reqBody, &resourceControl)
+	return
+}
diff --git a/client/resources.go b/client/resources.go
new file mode 100644
index 0000000..8ecfa9b
--- /dev/null
+++ b/client/resources.go
@@ -0,0 +1,30 @@
+package client
+
+type (
+	// ResourceType represents a type of Docker or Portainer resource
+	ResourceType string
+)
+
+const (
+	// ResourceContainer represents a Docker resource of type container
+	ResourceContainer = ResourceType("container")
+
+	// ResourceService represents a Docker resource of type service
+	ResourceService = ResourceType("service")
+
+	// ResourceVolume represents a Docker resource of type volume
+	ResourceVolume = ResourceType("volume")
+
+	// ResourceNetwork represents a Docker resource of type network
+	ResourceNetwork = ResourceType("network")
+
+	// ResourceSecret represents a Docker resource of type secret
+	ResourceSecret = ResourceType("secret")
+
+	// ResourceConfig represents a Docker resource of type config
+	ResourceConfig = ResourceType("config")
+
+	// ResourceStack represents a Portainer resource of type stack
+	// A Portainer stack is pretty much like a Docker stack, but not the same
+	ResourceStack = ResourceType("stack")
+)