diff --git a/lib/travis/api/v3.rb b/lib/travis/api/v3.rb
index 727d62ae..221df59b 100644
--- a/lib/travis/api/v3.rb
+++ b/lib/travis/api/v3.rb
@@ -30,7 +30,6 @@ module Travis
       WrongCredentials    = ClientError        .create('access denied',  status: 403)
       LoginRequired       = ClientError        .create('login required', status: 403)
       InsufficientAccess  = ClientError        .create(status: 403)
-      PushAccessRequired  = InsufficientAccess .create('push access required')
       WrongParams         = ClientError        .create('wrong parameters')
       ServerError         = Error              .create(status: 500)
       NotImplemented      = ServerError        .create('request not (yet) implemented', status: 501)
diff --git a/lib/travis/api/v3/access_control/generic.rb b/lib/travis/api/v3/access_control/generic.rb
index c4883ff3..0e09e409 100644
--- a/lib/travis/api/v3/access_control/generic.rb
+++ b/lib/travis/api/v3/access_control/generic.rb
@@ -36,8 +36,17 @@ module Travis::API::V3
       list.select { |r| visible?(r) }
     end
 
+    def permissions(object)
+      return unless factory = permission_class(object.class)
+      factory.new(self, object)
+    end
+
     protected
 
+    def account_visible?(account)
+      user and account.members.include?(user)
+    end
+
     def build_visible?(build)
       visible? build.repository
     end
@@ -78,13 +87,22 @@ module Travis::API::V3
       send(method, object) if respond_to?(method, true)
     end
 
-    @@method_for_cache = Tool::ThreadLocal.new
+
+    @@unknown_permission     = Object.new
+    @@permission_class_cache = Tool::ThreadLocal.new
+    @@method_for_cache       = Tool::ThreadLocal.new
+
+    def permission_class(klass)
+      result = @@permission_class_cache[klass] ||= Permissions[normailze_type(klass), false] || @@unknown_permission
+      result unless result == @@unknown_permission
+    end
 
     def method_for(type, method)
-      @@method_for_cache[[type, method]] ||= begin
-        prefix = type.name.sub(/^Travis::API::V3::Models::/, ''.freeze).underscore
-        "#{prefix}_#{method}"
-      end
+      @@method_for_cache[[type, method]] ||= "#{normailze_type(type)}_#{method}"
+    end
+
+    def normailze_type(type)
+      type.name.sub(/^Travis::API::V3::Models::/, ''.freeze).underscore.to_sym
     end
   end
 end
diff --git a/lib/travis/api/v3/access_control/scoped.rb b/lib/travis/api/v3/access_control/scoped.rb
index 5bf1df90..33b8017d 100644
--- a/lib/travis/api/v3/access_control/scoped.rb
+++ b/lib/travis/api/v3/access_control/scoped.rb
@@ -2,18 +2,27 @@ require 'travis/api/v3/access_control/generic'
 
 module Travis::API::V3
   class AccessControl::Scoped < AccessControl::Generic
-    attr_accessor :unscoped, :owner_name, :name
+    attr_accessor :unscoped, :anonymous, :owner_name, :name
 
     def initialize(scope, unscoped)
       @owner_name, @name = scope.split(?/.freeze, 2)
       @unscoped          = unscoped
+      @anonymous         = AccessControl::Anonymous.new
     end
 
     protected
 
     def private_repository_visible?(repository)
+      scope_repository(repository).visible?(repository)
+    end
+
+    def repository_writable?(repository)
+      scope_repository(repository).writable?(repository)
+    end
+
+    def scope_repository(repository, method = caller_locations.first.base_label)
       return false if name and repository.name != name
-      unscoped.visible?(repository) if repository.owner_name == owner_name
+      repository.owner_name == owner_name ? unscoped : anonymous
     end
   end
 end
diff --git a/lib/travis/api/v3/access_control/user.rb b/lib/travis/api/v3/access_control/user.rb
index f1979dfa..b0b93f15 100644
--- a/lib/travis/api/v3/access_control/user.rb
+++ b/lib/travis/api/v3/access_control/user.rb
@@ -2,12 +2,12 @@ require 'travis/api/v3/access_control/generic'
 
 module Travis::API::V3
   class AccessControl::User < AccessControl::Generic
-    attr_reader :user, :permissions
+    attr_reader :user, :access_permissions
 
     def initialize(user)
-      user         = Models::User.find(user.id) if user.is_a? ::User
-      @user        = user
-      @permissions = user.permissions.where(user_id: user.id)
+      user                = Models::User.find(user.id) if user.is_a? ::User
+      @user               = user
+      @access_permissions = user.permissions.where(user_id: user.id)
       super()
     end
 
@@ -20,11 +20,19 @@ module Travis::API::V3
     end
 
     def visible_repositories(list)
-      list.where('repositories.private = false OR repositories.id IN (?)'.freeze, permissions.map(&:repository_id))
+      list.where('repositories.private = false OR repositories.id IN (?)'.freeze, access_permissions.map(&:repository_id))
     end
 
     protected
 
+    def organization_writable?(organization)
+      organization.members.include? user
+    end
+
+    def user_writable?(user)
+      user == self.user
+    end
+
     def repository_writable?(repository)
       permission?(:push, repository)
     end
@@ -35,7 +43,7 @@ module Travis::API::V3
 
     def permission?(type, id)
       id = id.id if id.is_a? ::Repository
-      permissions.where(type => true, :repository_id => id).any?
+      access_permissions.where(type => true, :repository_id => id).any?
     end
   end
 end
diff --git a/lib/travis/api/v3/models/account.rb b/lib/travis/api/v3/models/account.rb
index a78a4b13..53f45fd0 100644
--- a/lib/travis/api/v3/models/account.rb
+++ b/lib/travis/api/v3/models/account.rb
@@ -23,6 +23,20 @@ module Travis::API::V3
       subscription.present? and subscription.active?
     end
 
+    def members
+      @members ||= if owner.respond_to? :members
+        owner.members
+      else
+        [owner]
+      end
+    end
+
+    def reload
+      @members = nil
+      owner.reload
+      self
+    end
+
     alias_method :educational, :educational?
     alias_method :subscribed,  :subscribed?
   end
diff --git a/lib/travis/api/v3/models/organization.rb b/lib/travis/api/v3/models/organization.rb
index 973487ed..224f0b8e 100644
--- a/lib/travis/api/v3/models/organization.rb
+++ b/lib/travis/api/v3/models/organization.rb
@@ -8,5 +8,7 @@ module Travis::API::V3
     def subscription
       super if Features.use_subscriptions?
     end
+
+    alias members users
   end
 end
diff --git a/lib/travis/api/v3/permissions.rb b/lib/travis/api/v3/permissions.rb
new file mode 100644
index 00000000..8b4c58b7
--- /dev/null
+++ b/lib/travis/api/v3/permissions.rb
@@ -0,0 +1,5 @@
+module Travis::API::V3
+  module Permissions
+    extend ConstantResolver
+  end
+end
diff --git a/lib/travis/api/v3/permissions/account.rb b/lib/travis/api/v3/permissions/account.rb
new file mode 100644
index 00000000..a161b62d
--- /dev/null
+++ b/lib/travis/api/v3/permissions/account.rb
@@ -0,0 +1,6 @@
+require 'travis/api/v3/permissions/generic'
+
+module Travis::API::V3
+  class Permissions::Account < Permissions::Generic
+  end
+end
diff --git a/lib/travis/api/v3/permissions/generic.rb b/lib/travis/api/v3/permissions/generic.rb
new file mode 100644
index 00000000..5648adfd
--- /dev/null
+++ b/lib/travis/api/v3/permissions/generic.rb
@@ -0,0 +1,60 @@
+module Travis::API::V3
+  class Permissions::Generic
+    def self.access_rights
+      @access_rights ||= begin
+        rights = superclass.respond_to?(:access_rights) ? superclass.access_rights.dup : {}
+        public_instance_methods(false).each do |method|
+          next unless method.to_s =~ /^([^_].+)\?$/
+          rights[$1.to_sym] = method
+        end
+        rights
+      end
+    end
+
+    # for any public method defined with a question mark in the end, it defines a method with an
+    # exclamation mark that will raise an InsufficientAccess error if the question mark version
+    # returns false
+    def self.method_added(method_name)
+      super
+
+      return unless public_method_defined?(method_name)
+      return unless method_name.to_s =~ /^([^_].+)\?$/
+
+      permission = $1
+      type       = name[/[^:]+$/].underscore
+
+      class_eval <<-RUBY
+        def #{permission}!
+          return self if #{permission}?
+          payload = {
+            resource_type: "#{type}".freeze,
+            permission:    "#{permission}".freeze
+          }
+          payload[:#{type}] = object if read?
+          raise InsufficientAccess.new('operation requires #{permission} access to #{type}', payload)
+        end
+      RUBY
+    end
+
+    attr_accessor :access_control, :object
+
+    def initialize(access_control, object)
+      @access_control = access_control
+      @object         = object
+    end
+
+    def read?
+      access_control.visible? object
+    end
+
+    def to_h
+      self.class.access_rights.map { |k,v| [k,!!public_send(v)] }.to_h
+    end
+
+    private
+
+    def write?
+      access_control.writable? object
+    end
+  end
+end
diff --git a/lib/travis/api/v3/permissions/organization.rb b/lib/travis/api/v3/permissions/organization.rb
new file mode 100644
index 00000000..1693d975
--- /dev/null
+++ b/lib/travis/api/v3/permissions/organization.rb
@@ -0,0 +1,9 @@
+require 'travis/api/v3/permissions/generic'
+
+module Travis::API::V3
+  class Permissions::Organization < Permissions::Generic
+    def sync?
+      write?
+    end
+  end
+end
diff --git a/lib/travis/api/v3/permissions/repository.rb b/lib/travis/api/v3/permissions/repository.rb
new file mode 100644
index 00000000..75f47597
--- /dev/null
+++ b/lib/travis/api/v3/permissions/repository.rb
@@ -0,0 +1,17 @@
+require 'travis/api/v3/permissions/generic'
+
+module Travis::API::V3
+  class Permissions::Repository < Permissions::Generic
+    def enable?
+      write?
+    end
+
+    def disable?
+      write?
+    end
+
+    def create_request?
+      write?
+    end
+  end
+end
diff --git a/lib/travis/api/v3/permissions/user.rb b/lib/travis/api/v3/permissions/user.rb
new file mode 100644
index 00000000..6aaf5af2
--- /dev/null
+++ b/lib/travis/api/v3/permissions/user.rb
@@ -0,0 +1,9 @@
+require 'travis/api/v3/permissions/generic'
+
+module Travis::API::V3
+  class Permissions::User < Permissions::Generic
+    def sync?
+      write?
+    end
+  end
+end
diff --git a/lib/travis/api/v3/renderer/model_renderer.rb b/lib/travis/api/v3/renderer/model_renderer.rb
index 491aa627..b62c8537 100644
--- a/lib/travis/api/v3/renderer/model_renderer.rb
+++ b/lib/travis/api/v3/renderer/model_renderer.rb
@@ -43,7 +43,7 @@ module Travis::API::V3
       @script_name    = script_name
       @include        = include
       @included       = included
-      @access_control = access_control
+      @access_control = access_control || AccessControl::Anonymous.new
     end
 
     def href
@@ -74,19 +74,26 @@ module Travis::API::V3
       nested_included = included + [model]
       modes           = {}
 
+      if permissions = access_control.permissions(model) and (representation != :minimal or include? :@permissions)
+        result[:@permissions] = permissions.to_h
+      end
+
       if include.any?
         excepted_type = result[:@type].to_s
         fields        = fields.dup
       end
 
       include.each do |qualified_field|
-        raise WrongParams, 'illegal format for include parameter'.freeze unless /\A(?<prefix>\w+)\.(?<field>\w+)\Z$/ =~ qualified_field
+        raise WrongParams, 'illegal format for include parameter'.freeze unless /\A(?<prefix>\w+)\.(?<field>@?\w+)\Z$/ =~ qualified_field
         next if prefix != excepted_type
-        raise WrongParams, 'no field %p to include'.freeze % qualified_field unless self.class.available_attributes.include?(field)
 
-        field &&= field.to_sym
-        fields << field unless fields.include?(field)
-        modes[field] = :standard
+        if self.class.available_attributes.include?(field)
+          field &&= field.to_sym
+          fields << field unless fields.include?(field)
+          modes[field] = :standard
+        else
+          raise WrongParams, 'no field %p to include'.freeze % qualified_field unless result.keys.any? { |k| k.to_s == field.to_s }
+        end
       end
   
       fields.each do |field|
diff --git a/lib/travis/api/v3/services/repository/disable.rb b/lib/travis/api/v3/services/repository/disable.rb
index 08a191bb..c904351e 100644
--- a/lib/travis/api/v3/services/repository/disable.rb
+++ b/lib/travis/api/v3/services/repository/disable.rb
@@ -3,6 +3,7 @@ module Travis::API::V3
     def run!(activate = false)
       raise LoginRequired unless access_control.logged_in? or access_control.full_access?
       raise NotFound      unless repository = find(:repository)
+      check_access(repository)
 
       admin = access_control.admin_for(repository)
 
@@ -11,5 +12,9 @@ module Travis::API::V3
 
       repository
     end
+
+    def check_access(repository)
+      access_control.permissions(repository).disable!
+    end
   end
 end
diff --git a/lib/travis/api/v3/services/repository/enable.rb b/lib/travis/api/v3/services/repository/enable.rb
index 5d85439b..5d43bbe7 100644
--- a/lib/travis/api/v3/services/repository/enable.rb
+++ b/lib/travis/api/v3/services/repository/enable.rb
@@ -3,5 +3,9 @@ module Travis::API::V3
     def run!
       super(true)
     end
+
+    def check_access(repository)
+      access_control.permissions(repository).enable!
+    end
   end
 end
diff --git a/lib/travis/api/v3/services/requests/create.rb b/lib/travis/api/v3/services/requests/create.rb
index 2ff6f156..40a299c5 100644
--- a/lib/travis/api/v3/services/requests/create.rb
+++ b/lib/travis/api/v3/services/requests/create.rb
@@ -8,9 +8,9 @@ module Travis::API::V3
     params "request", "user", :config, :message, :branch
 
     def run
-      raise LoginRequired                              unless access_control.logged_in? or access_control.full_access?
-      raise NotFound                                   unless repository = find(:repository)
-      raise PushAccessRequired, repository: repository unless access_control.writable?(repository)
+      raise LoginRequired unless access_control.logged_in? or access_control.full_access?
+      raise NotFound      unless repository = find(:repository)
+      access_control.permissions(repository).create_request!
 
       user      = find(:user) if access_control.full_access? and params_for? 'user'.freeze
       user    ||= access_control.user
diff --git a/spec/v3/services/accounts/for_current_user_spec.rb b/spec/v3/services/accounts/for_current_user_spec.rb
index 01d45c9a..e50b36e6 100644
--- a/spec/v3/services/accounts/for_current_user_spec.rb
+++ b/spec/v3/services/accounts/for_current_user_spec.rb
@@ -22,6 +22,7 @@ describe Travis::API::V3::Services::Accounts::ForCurrentUser do
       "@href"          => "/v3/accounts",
       "accounts"       => [{
         "@type"        => "account",
+        "@permissions" => { "read"=>true },
         "id"           => repo.owner.github_id,
         "subscribed"   => false,
         "educational"  => false,
@@ -31,6 +32,7 @@ describe Travis::API::V3::Services::Accounts::ForCurrentUser do
           "id"         => repo.owner_id,
           "login"      => "svenfuchs" }},
        {"@type"        => "account",
+        "@permissions" => { "read"=>true },
         "id"           => 42,
         "subscribed"   => false,
         "educational"  => false,
diff --git a/spec/v3/services/organization/find_spec.rb b/spec/v3/services/organization/find_spec.rb
index 030aa172..2245441a 100644
--- a/spec/v3/services/organization/find_spec.rb
+++ b/spec/v3/services/organization/find_spec.rb
@@ -9,13 +9,14 @@ describe Travis::API::V3::Services::Organization::Find do
     before  { get("/v3/org/#{org.id}")       }
     example { expect(last_response).to be_ok }
     example { expect(JSON.load(body)).to be == {
-      "@type"      => "organization",
-      "@href"      => "/v3/org/#{org.id}",
-      "id"         => org.id,
-      "login"      => "example-org",
-      "name"       => nil,
-      "github_id"  => nil,
-      "avatar_url" => nil
+      "@type"        => "organization",
+      "@href"        => "/v3/org/#{org.id}",
+      "@permissions" => { "read"=>true, "sync"=>false },
+      "id"           => org.id,
+      "login"        => "example-org",
+      "name"         => nil,
+      "github_id"    => nil,
+      "avatar_url"   => nil
     }}
   end
 end
diff --git a/spec/v3/services/organizations/for_current_user_spec.rb b/spec/v3/services/organizations/for_current_user_spec.rb
index f402e7cd..dfdf1517 100644
--- a/spec/v3/services/organizations/for_current_user_spec.rb
+++ b/spec/v3/services/organizations/for_current_user_spec.rb
@@ -18,16 +18,17 @@ describe Travis::API::V3::Services::Organizations::ForCurrentUser do
     before  { get("/v3/orgs", {}, headers)     }
     example { expect(last_response).to be_ok   }
     example { expect(JSON.load(body)).to be == {
-      "@type"         => "organizations",
-      "@href"         => "/v3/orgs",
-      "organizations" => [{
-        "@type"       => "organization",
-        "@href"       => "/v3/org/#{org.id}",
-        "id"          => org.id,
-        "login"       => "example-org",
-        "name"        => nil,
-        "github_id"   => nil,
-        "avatar_url"  => nil
+      "@type"          => "organizations",
+      "@href"          => "/v3/orgs",
+      "organizations"  => [{
+        "@type"        => "organization",
+        "@href"        => "/v3/org/#{org.id}",
+        "@permissions" => { "read"=>true, "sync"=>true },
+        "id"           => org.id,
+        "login"        => "example-org",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil
       }]
     }}
   end
diff --git a/spec/v3/services/owner/find_spec.rb b/spec/v3/services/owner/find_spec.rb
index 90152fd8..66d3feca 100644
--- a/spec/v3/services/owner/find_spec.rb
+++ b/spec/v3/services/owner/find_spec.rb
@@ -10,13 +10,14 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-org")     }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "organization",
-        "@href"      => "/v3/org/#{org.id}",
-        "id"         => org.id,
-        "login"      => "example-org",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil
+        "@type"        => "organization",
+        "@href"        => "/v3/org/#{org.id}",
+        "@permissions" => { "read"=>true, "sync"=>false },
+        "id"           => org.id,
+        "login"        => "example-org",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil
       }}
     end
 
@@ -31,6 +32,7 @@ describe Travis::API::V3::Services::Owner::Find do
       example { expect(JSON.load(body)).to be == {
         "@type"             => "organization",
         "@href"             => "/v3/org/#{org.id}",
+        "@permissions"      => { "read"=>true, "sync"=>false },
         "id"                => org.id,
         "login"             => "example-org",
         "name"              => nil,
@@ -39,6 +41,11 @@ describe Travis::API::V3::Services::Owner::Find do
         "repositories"      => [{
           "@type"           => "repository",
           "@href"           => "/v3/repo/#{repo.id}",
+          "@permissions"    => {
+            "read"          => true,
+            "enable"        => false,
+            "disable"       => false,
+            "create_request"=> false},
           "id"              => repo.id,
           "name"            => "example-repo",
           "slug"            => "example-org/example-repo",
@@ -68,6 +75,7 @@ describe Travis::API::V3::Services::Owner::Find do
       example { expect(JSON.load(body)).to be == {
         "@type"             => "organization",
         "@href"             => "/v3/org/#{org.id}",
+        "@permissions"      => { "read"=>true, "sync"=>false },
         "id"                => org.id,
         "login"             => "example-org",
         "name"              => nil,
@@ -76,6 +84,11 @@ describe Travis::API::V3::Services::Owner::Find do
         "repositories"      => [{
           "@type"           => "repository",
           "@href"           => "/v3/repo/#{repo.id}",
+          "@permissions"    => {
+            "read"          => true,
+            "enable"        => false,
+            "disable"       => false,
+            "create_request"=> false},
           "id"              => repo.id,
           "name"            => "example-repo",
           "slug"            => "example-org/example-repo",
@@ -98,13 +111,14 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-ORG")     }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "organization",
-        "@href"      => "/v3/org/#{org.id}",
-        "id"         => org.id,
-        "login"      => "example-org",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil
+        "@type"        => "organization",
+        "@href"        => "/v3/org/#{org.id}",
+        "@permissions" => { "read"=>true, "sync"=>false },
+        "id"           => org.id,
+        "login"        => "example-org",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil
       }}
     end
 
@@ -116,13 +130,14 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-org?organization.id=#{other.id}") }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "organization",
-        "@href"      => "/v3/org/#{org.id}",
-        "id"         => org.id,
-        "login"      => "example-org",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil
+        "@type"        => "organization",
+        "@href"        => "/v3/org/#{org.id}",
+        "@permissions" => { "read"=>true, "sync"=>false },
+        "id"           => org.id,
+        "login"        => "example-org",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil
       }}
     end
   end
@@ -136,15 +151,16 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-user")   }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "user",
-        "@href"      => "/v3/user/#{user.id}",
-        "id"         => user.id,
-        "login"      => "example-user",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil,
-        "is_syncing" => nil,
-        "synced_at"  => nil
+        "@type"        => "user",
+        "@href"        => "/v3/user/#{user.id}",
+        "@permissions" => {"read"=>true, "sync"=>false},
+        "id"           => user.id,
+        "login"        => "example-user",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil,
+        "is_syncing"   => nil,
+        "synced_at"    => nil
       }}
     end
 
@@ -152,15 +168,16 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-USER")   }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "user",
-        "@href"      => "/v3/user/#{user.id}",
-        "id"         => user.id,
-        "login"      => "example-user",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil,
-        "is_syncing" => nil,
-        "synced_at"  => nil
+        "@type"        => "user",
+        "@href"        => "/v3/user/#{user.id}",
+        "@permissions" => {"read"=>true, "sync"=>false},
+        "id"           => user.id,
+        "login"        => "example-user",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil,
+        "is_syncing"   => nil,
+        "synced_at"    => nil
       }}
     end
 
@@ -172,15 +189,16 @@ describe Travis::API::V3::Services::Owner::Find do
       before  { get("/v3/owner/example-user?user.id=#{other.id}") }
       example { expect(last_response).to be_ok   }
       example { expect(JSON.load(body)).to be == {
-        "@type"      => "user",
-        "@href"      => "/v3/user/#{user.id}",
-        "id"         => user.id,
-        "login"      => "example-user",
-        "name"       => nil,
-        "github_id"  => nil,
-        "avatar_url" => nil,
-        "is_syncing" => nil,
-        "synced_at"  => nil
+        "@type"        => "user",
+        "@href"        => "/v3/user/#{user.id}",
+        "@permissions" => {"read"=>true, "sync"=>false},
+        "id"           => user.id,
+        "login"        => "example-user",
+        "name"         => nil,
+        "github_id"    => nil,
+        "avatar_url"   => nil,
+        "is_syncing"   => nil,
+        "synced_at"    => nil
       }}
     end
   end
diff --git a/spec/v3/services/owner/repositories_spec.rb b/spec/v3/services/owner/repositories_spec.rb
index 9f47fecb..77285bfc 100644
--- a/spec/v3/services/owner/repositories_spec.rb
+++ b/spec/v3/services/owner/repositories_spec.rb
@@ -18,6 +18,11 @@ describe Travis::API::V3::Services::Owner::Repositories do
       "repositories"      => [{
         "@type"           => "repository",
         "@href"           => "/v3/repo/#{repo.id}",
+        "@permissions"    => {
+          "read"          => true,
+          "enable"        => false,
+          "disable"       => false,
+          "create_request"=> false},
         "id"              =>  repo.id,
         "name"            =>  "minimal",
         "slug"            =>  "svenfuchs/minimal",
diff --git a/spec/v3/services/repositories/for_current_user_spec.rb b/spec/v3/services/repositories/for_current_user_spec.rb
index 67068f69..26fe6151 100644
--- a/spec/v3/services/repositories/for_current_user_spec.rb
+++ b/spec/v3/services/repositories/for_current_user_spec.rb
@@ -3,11 +3,11 @@ require 'spec_helper'
 describe Travis::API::V3::Services::Repositories::ForCurrentUser do
   let(:repo) { Repository.by_slug('svenfuchs/minimal').first }
 
-  let(:token)   { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1) }
-  let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}"                        }}
-  before        { Permission.create(repository: repo, user: repo.owner, pull: true) }
-  before        { repo.update_attribute(:private, true)                             }
-  after         { repo.update_attribute(:private, false)                            }
+  let(:token)   { Travis::Api::App::AccessToken.create(user: repo.owner, app_id: 1)             }
+  let(:headers) {{ 'HTTP_AUTHORIZATION' => "token #{token}"                                    }}
+  before        { Permission.create(repository: repo, user: repo.owner, pull: true, push: true) }
+  before        { repo.update_attribute(:private, true)                                         }
+  after         { repo.update_attribute(:private, false)                                        }
 
   describe "private repository, private API, authenticated as user with access" do
     before  { get("/v3/repos", {}, headers)    }
@@ -18,6 +18,11 @@ describe Travis::API::V3::Services::Repositories::ForCurrentUser do
       "repositories"      => [{
         "@type"           => "repository",
         "@href"           => "/v3/repo/#{repo.id}",
+        "@permissions"    => {
+          "read"          => true,
+          "enable"        => true,
+          "disable"       => true,
+          "create_request"=> true},
         "id"              =>  repo.id,
         "name"            =>  "minimal",
         "slug"            =>  "svenfuchs/minimal",
diff --git a/spec/v3/services/repository/find_spec.rb b/spec/v3/services/repository/find_spec.rb
index b92df8d0..d0d6d431 100644
--- a/spec/v3/services/repository/find_spec.rb
+++ b/spec/v3/services/repository/find_spec.rb
@@ -10,6 +10,11 @@ describe Travis::API::V3::Services::Repository::Find do
     example    { expect(parsed_body).to be == {
       "@type"           => "repository",
       "@href"           => "/v3/repo/#{repo.id}",
+      "@permissions"    => {
+        "read"          => true,
+        "enable"        => false,
+        "disable"       => false,
+        "create_request"=> false},
       "id"              =>  repo.id,
       "name"            =>  "minimal",
       "slug"            =>  "svenfuchs/minimal",
@@ -95,6 +100,11 @@ describe Travis::API::V3::Services::Repository::Find do
     example       { expect(parsed_body).to be == {
       "@type"           => "repository",
       "@href"           => "/v3/repo/#{repo.id}",
+      "@permissions"    => {
+        "read"          => true,
+        "enable"        => false,
+        "disable"       => false,
+        "create_request"=> false},
       "id"              =>  repo.id,
       "name"            =>  "minimal",
       "slug"            =>  "svenfuchs/minimal",
@@ -165,6 +175,11 @@ describe Travis::API::V3::Services::Repository::Find do
     example { expect(parsed_body).to be == {
       "@type"           => "repository",
       "@href"           => "/v3/repo/#{repo.id}",
+      "@permissions"    => {
+        "read"          => true,
+        "enable"        => true,
+        "disable"       => true,
+        "create_request"=> true},
       "id"              =>  repo.id,
       "name"            =>  "minimal",
       "slug"            =>  "svenfuchs/minimal",
@@ -241,6 +256,11 @@ describe Travis::API::V3::Services::Repository::Find do
     example { expect(parsed_body).to be == {
       "@type"           => "repository",
       "@href"           => "/v3/repo/#{repo.id}",
+      "@permissions"    => {
+        "read"          => true,
+        "enable"        => true,
+        "disable"       => true,
+        "create_request"=> true},
       "id"              =>  repo.id,
       "name"            =>  "minimal",
       "slug"            =>  "svenfuchs/minimal",
diff --git a/spec/v3/services/requests/create_spec.rb b/spec/v3/services/requests/create_spec.rb
index 62b32089..b316ca82 100644
--- a/spec/v3/services/requests/create_spec.rb
+++ b/spec/v3/services/requests/create_spec.rb
@@ -49,8 +49,10 @@ describe Travis::API::V3::Services::Requests::Create do
     example { expect(last_response.status).to be == 403 }
     example { expect(JSON.load(body)).to      be ==     {
       "@type"         => "error",
-      "error_type"    => "push_access_required",
-      "error_message" => "push access required",
+      "error_type"    => "insufficient_access",
+      "error_message" => "operation requires create_request access to repository",
+      "resource_type" => "repository",
+      "permission"    => "create_request",
       "repository"    => {
         "@type"       => "repository",
         "@href"       => "/repo/#{repo.id}",
diff --git a/spec/v3/services/user/current_spec.rb b/spec/v3/services/user/current_spec.rb
index 443671e6..88a1c920 100644
--- a/spec/v3/services/user/current_spec.rb
+++ b/spec/v3/services/user/current_spec.rb
@@ -10,15 +10,16 @@ describe Travis::API::V3::Services::User::Current do
     before  { get("/v3/user", {}, headers)     }
     example { expect(last_response).to be_ok   }
     example { expect(JSON.load(body)).to be == {
-      "@type"      => "user",
-      "@href"      => "/v3/user/#{user.id}",
-      "id"         => user.id,
-      "login"      => "svenfuchs",
-      "name"       =>"Sven Fuchs",
-      "github_id"  => user.github_id,
-      "avatar_url" => "https://0.gravatar.com/avatar/07fb84848e68b96b69022d333ca8a3e2",
-      "is_syncing" => user.is_syncing,
-      "synced_at"  => user.synced_at
+      "@type"        => "user",
+      "@href"        => "/v3/user/#{user.id}",
+      "@permissions" => {"read"=>true, "sync"=>true},
+      "id"           => user.id,
+      "login"        => "svenfuchs",
+      "name"         =>"Sven Fuchs",
+      "github_id"    => user.github_id,
+      "avatar_url"   => "https://0.gravatar.com/avatar/07fb84848e68b96b69022d333ca8a3e2",
+      "is_syncing"   => user.is_syncing,
+      "synced_at"    => user.synced_at
     }}
   end
 end
\ No newline at end of file
diff --git a/spec/v3/services/user/find_spec.rb b/spec/v3/services/user/find_spec.rb
index 30ee4800..b493bc40 100644
--- a/spec/v3/services/user/find_spec.rb
+++ b/spec/v3/services/user/find_spec.rb
@@ -10,15 +10,16 @@ describe Travis::API::V3::Services::User::Find do
     before  { get("/v3/user/#{user.id}", {}, headers) }
     example { expect(last_response).to be_ok          }
     example { expect(JSON.load(body)).to be ==        {
-      "@type"      => "user",
-      "@href"      => "/v3/user/#{user.id}",
-      "id"         => user.id,
-      "login"      => "svenfuchs",
-      "name"       =>"Sven Fuchs",
-      "github_id"  => user.github_id,
-      "avatar_url" => "https://0.gravatar.com/avatar/07fb84848e68b96b69022d333ca8a3e2",
-      "is_syncing" => user.is_syncing,
-      "synced_at"  => user.synced_at
+      "@type"        => "user",
+      "@href"        => "/v3/user/#{user.id}",
+      "@permissions" => {"read"=>true, "sync"=>true},
+      "id"           => user.id,
+      "login"        => "svenfuchs",
+      "name"         =>"Sven Fuchs",
+      "github_id"    => user.github_id,
+      "avatar_url"   => "https://0.gravatar.com/avatar/07fb84848e68b96b69022d333ca8a3e2",
+      "is_syncing"   => user.is_syncing,
+      "synced_at"    => user.synced_at
     }}
   end
 end
\ No newline at end of file