diff --git a/setup.py b/setup.py
index e386efb..2c1f362 100644
--- a/setup.py
+++ b/setup.py
@@ -9,7 +9,7 @@ except IOError:
     README = CHANGES = ''
 
 requires = [
-    'pyramid',
+    'pyramid>=2.0',
     'zope.interface',
     'pyramid_services>=0.3'
 ]
@@ -27,7 +27,7 @@ docs_require = requires + [
 
 setup(
     name='pyramid_authsanity',
-    version='1.1.0',
+    version='2.0.0',
     description='An auth policy for the Pyramid Web Framework with sane defaults.',
     long_description=README + '\n\n' + CHANGES,
     classifiers=[
@@ -36,11 +36,10 @@ setup(
         'Intended Audience :: Developers',
         'License :: OSI Approved :: ISC License (ISCL)',
         'Programming Language :: Python',
-        'Programming Language :: Python :: 2.6',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: Implementation :: CPython',
         'Programming Language :: Python :: Implementation :: PyPy',
     ],
diff --git a/src/pyramid_authsanity/policy.py b/src/pyramid_authsanity/policy.py
index d30d392..96b6d0f 100644
--- a/src/pyramid_authsanity/policy.py
+++ b/src/pyramid_authsanity/policy.py
@@ -6,7 +6,7 @@ from pyramid.interfaces import (
     IDebugLogger,
     )
 
-from pyramid.security import (
+from pyramid.authorization import (
     Authenticated,
     Everyone,
     )
diff --git a/src/pyramid_authsanity/sources.py b/src/pyramid_authsanity/sources.py
index 48d392b..ff9a047 100644
--- a/src/pyramid_authsanity/sources.py
+++ b/src/pyramid_authsanity/sources.py
@@ -1,5 +1,3 @@
-from pyramid.compat import native_
-
 from webob.cookies import (
     JSONSerializer,
     SignedCookieProfile,
@@ -129,6 +127,13 @@ def HeaderAuthSourceInitializer(
                 serializer=serializer,
                 )
 
+        def _native(s, encoding='latin-1', errors='strict'):
+            """If ``s`` is an instance of ``str``, return
+            ``s``, otherwise return ``str(s, encoding, errors)``"""
+            if isinstance(s, str):
+                return s
+            return str(s, encoding, errors)
+
         def _get_authorization(self):
             try:
                 type, token = self.request.authorization
@@ -154,7 +159,7 @@ def HeaderAuthSourceInitializer(
                 self.cur_val = None
 
             token = self._create_authorization(value)
-            auth_info = native_(b'Bearer ' + token, 'latin-1', 'strict')
+            auth_info = self._native(b'Bearer ' + token, 'latin-1', 'strict')
             return [('Authorization', auth_info)]
 
         def headers_forget(self):
diff --git a/tox.ini b/tox.ini
index a0e4462..a197356 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,54 +1,79 @@
 [tox]
 envlist =
     lint,
-    py27,py34,py35,py36,pypy,
-    docs,coverage
+    py36,py37,py38,py39,pypy3
+    py39-cover,coverage,
+    docs
 
 [testenv]
-basepython =
-    py27: python2.7
-    py34: python3.4
-    py35: python3.5
-    py36: python3.6
-    py37: python3.7
-    pypy: pypy
-    pypy3: pypy3
-
 commands =
-    pip install pyramid_authsanity[testing]
-    py.test --cov --cov-report= {posargs:}
-
+    python --version
+    pytest {posargs:}
+extras =
+    testing
 setenv =
     COVERAGE_FILE=.coverage.{envname}
 
+[testenv:py39-cover]
+commands =
+    python --version
+    pytest --cov {posargs:}
+
 [testenv:coverage]
 skip_install = True
-basepython = python3.6
 commands =
     coverage combine
+    coverage xml
     coverage report --fail-under=100
 deps =
     coverage
 setenv =
     COVERAGE_FILE=.coverage
+depends = py39-cover
 
 [testenv:docs]
-basepython = python3.6
 whitelist_externals =
     make
 commands =
     pip install pyramid_authsanity[docs]
-    make -C docs html BUILDDIR={envdir} SPHINXOPTS="-W -E"
+    make -C docs html BUILDDIR={envdir} "SPHINXOPTS=-W -E -D suppress_warnings=ref.term"
+extras =
+    docs
 
 [testenv:lint]
 skip_install = True
-basepython = python3.6
 commands =
-    flake8 src/pyramid_authsanity/
+    flake8 src/pyramid_authsanity/ tests setup.py
+    isort --check-only --df  src/pyramid tests setup.py
+    black --check --diff src/pyramid tests setup.py
     python setup.py check -r -s -m
     check-manifest
 deps =
+    black
+    check-manifest
     flake8
+    isort
     readme_renderer
-    check-manifest
 
+[testenv:format]
+skip_install = true
+commands =
+    isort src/pyramid tests setup.py
+    black src/pyramid tests setup.py
+deps =
+    black
+    isort
+
+[testenv:build]
+skip_install = true
+commands =
+    # clean up build/ and dist/ folders
+    python -c 'import shutil; shutil.rmtree("dist", ignore_errors=True)'
+    python setup.py clean --all
+    # build sdist
+    python setup.py sdist --dist-dir {toxinidir}/dist
+    # build wheel from sdist
+    pip wheel -v --no-deps --no-index --no-build-isolation --wheel-dir {toxinidir}/dist --find-links {toxinidir}/dist pyramid_authsanity
+deps =
+    setuptools
+    wheel

diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml
new file mode 100644
index 0000000..f2debd8
--- /dev/null
+++ b/.github/workflows/ci-tests.yml
@@ -0,0 +1,95 @@
+name: Build and test
+
+on:
+    # Only on pushes to master or one of the release branches we build on push
+    push:
+        branches:
+            - master
+        tags:
+    # Build pull requests
+    pull_request:
+
+jobs:
+    test:
+        strategy:
+            matrix:
+                py:
+                    - "3.6"
+                    - "3.7"
+                    - "3.8"
+                    - "3.9"
+                    - "pypy3"
+                os:
+                    - "ubuntu-latest"
+                    - "windows-latest"
+                    - "macos-latest"
+                architecture:
+                    - x64
+                    - x86
+
+                include:
+                    # Only run coverage on ubuntu-latest, except on pypy3
+                    - os: "ubuntu-latest"
+                      pytest-args: "--cov"
+                    - os: "ubuntu-latest"
+                      py: "pypy3"
+                      pytest-args: ""
+
+                exclude:
+                    # Linux and macOS don't have x86 python
+                    - os: "ubuntu-latest"
+                      architecture: x86
+                    - os: "macos-latest"
+                      architecture: x86
+                    # PyPy3 on Windows doesn't seem to work
+                    - os: "windows-latest"
+                      py: "pypy3"
+
+        name: "Python: ${{ matrix.py }}-${{ matrix.architecture }} on ${{ matrix.os }}"
+        runs-on: ${{ matrix.os }}
+        steps:
+            - uses: actions/checkout@v2
+            - name: Setup python
+              uses: actions/setup-python@v2
+              with:
+                  python-version: ${{ matrix.py }}
+                  architecture: ${{ matrix.architecture }}
+            - run: pip install tox
+            - name: Running tox
+              run: tox -e py -- ${{ matrix.pytest-args }}
+    coverage:
+        runs-on: ubuntu-latest
+        name: Validate coverage
+        steps:
+            - uses: actions/checkout@v2
+            - name: Setup python
+              uses: actions/setup-python@v1
+              with:
+                  python-version: 3.9
+                  architecture: x64
+            - run: pip install tox
+            - run: tox -e py39-cover,coverage
+    docs:
+        runs-on: ubuntu-latest
+        name: Build the documentation
+        steps:
+            - uses: actions/checkout@v2
+            - name: Setup python
+              uses: actions/setup-python@v2
+              with:
+                  python-version: 3.9
+                  architecture: x64
+            - run: pip install tox
+            - run: tox -e docs
+    lint:
+        runs-on: ubuntu-latest
+        name: Lint the package
+        steps:
+            - uses: actions/checkout@v2
+            - name: Setup python
+              uses: actions/setup-python@v2
+              with:
+                  python-version: 3.9
+                  architecture: x64
+            - run: pip install tox
+            - run: tox -e lint
diff --git a/tests/test_authpolicy.py b/tests/test_authpolicy.py
index 6eadb85..99f2c84 100644
--- a/tests/test_authpolicy.py
+++ b/tests/test_authpolicy.py
@@ -18,7 +18,7 @@ from pyramid_authsanity.interfaces import (
 
 def test_clean_principal_invalid():
     from pyramid_authsanity.policy import _clean_principal
-    from pyramid.security import Everyone
+    from pyramid.authorization import Everyone
 
     ret = _clean_principal(Everyone)
 
@@ -129,7 +129,7 @@ class TestAuthServicePolicy(object):
         assert authuserid is None
 
     def test_no_user_effective_principals(self):
-        from pyramid.security import Everyone
+        from pyramid.authorization import Everyone
         context = None
         request = self._makeOneRequest()
         source = fake_source_init([None, None])(context, request)
@@ -142,7 +142,7 @@ class TestAuthServicePolicy(object):
         assert [Everyone] == groups
 
     def test_user_bad_principal_effective_principals(self):
-        from pyramid.security import Everyone
+        from pyramid.authorization import Everyone
         context = None
         request = self._makeOneRequest()
         source = fake_source_init([Everyone, 'valid'])(context, request)
@@ -155,7 +155,7 @@ class TestAuthServicePolicy(object):
         assert [Everyone] == groups
 
     def test_effective_principals(self):
-        from pyramid.security import Everyone, Authenticated
+        from pyramid.authorization import Everyone, Authenticated
         context = None
         request = self._makeOneRequest()
         source = fake_source_init(['test', 'valid'])(context, request)
@@ -306,7 +306,7 @@ class TestAuthServicePolicyIntegration(object):
         assert authuserid is None
 
     def test_no_user_effective_principals(self):
-        from pyramid.security import Everyone
+        from pyramid.authorization import Everyone
         request = self._makeOneRequest()
         source = fake_source_init([None, None])
         auth = fake_auth_init()
@@ -318,7 +318,7 @@ class TestAuthServicePolicyIntegration(object):
         assert [Everyone] == groups
 
     def test_user_bad_principal_effective_principals(self):
-        from pyramid.security import Everyone
+        from pyramid.authorization import Everyone
         request = self._makeOneRequest()
         source = fake_source_init([Everyone, 'valid'])
         auth = fake_auth_init(fake_userid=Everyone, valid_tickets=['valid'])
@@ -330,7 +330,7 @@ class TestAuthServicePolicyIntegration(object):
         assert [Everyone] == groups
 
     def test_effective_principals(self):
-        from pyramid.security import Everyone, Authenticated
+        from pyramid.authorization import Everyone, Authenticated
         request = self._makeOneRequest()
         source = fake_source_init(['test', 'valid'])
         auth = fake_auth_init(fake_userid='test', valid_tickets=['valid'])

Support Pyramid 2.0
`pyramid.compat` has been removed, causing this import to fail:

https://github.com/usingnamespace/pyramid_authsanity/blob/8ecbe63dba8f6db57c9e216fecde303e0d942461/src/pyramid_authsanity/sources.py#L1
tests/test_authpolicy.py::test_clean_principal_invalid tests/test_authpolicy.py::test_clean_principal_valid tests/test_authpolicy.py::TestAuthServicePolicyInterface::test_verify tests/test_authpolicy.py::TestAuthServicePolicy::test_find_services tests/test_authpolicy.py::TestAuthServicePolicy::test_fake_source_ticket tests/test_authpolicy.py::TestAuthServicePolicy::test_valid_source_ticket tests/test_authpolicy.py::TestAuthServicePolicy::test_invalid_source_ticket tests/test_authpolicy.py::TestAuthServicePolicy::test_bad_auth_service tests/test_authpolicy.py::TestAuthServicePolicy::test_no_user_effective_principals tests/test_authpolicy.py::TestAuthServicePolicy::test_user_bad_principal_effective_principals tests/test_authpolicy.py::TestAuthServicePolicy::test_effective_principals tests/test_authpolicy.py::TestAuthServicePolicy::test_remember tests/test_authpolicy.py::TestAuthServicePolicy::test_forget tests/test_authpolicy.py::TestAuthServicePolicyIntegration::test_include_me tests/test_authpolicy.py::TestAuthServicePolicyIntegration::test_logging