diff --git a/changelog/824.feature.rst b/changelog/824.feature.rst
new file mode 100644
index 00000000..aae99136
--- /dev/null
+++ b/changelog/824.feature.rst
@@ -0,0 +1,1 @@
+use the os environment variable ``TOX_SKIP_ENV`` to filter out tox environment names from the run list (set by :confval:`envlist`)  - by :user:`gaborbernat`
diff --git a/changelog/838.feature.rst b/changelog/838.feature.rst
new file mode 100644
index 00000000..b90ff843
--- /dev/null
+++ b/changelog/838.feature.rst
@@ -0,0 +1,1 @@
+always set ``PIP_USER=0`` (do not install into the user site package, but inside the virtual environment created) and ``PIP_NO_DEPS=0`` (installing without dependencies can cause broken package installations) inside tox - by :user:`gaborbernat`
diff --git a/doc/config.rst b/doc/config.rst
index 89ce7a3a..7c33646a 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -76,6 +76,13 @@ and will first lookup global tox settings in this section:
     * environment variable ``TOXENV``
     * ``tox.ini`` file's ``envlist``
 
+    .. versionadded:: 3.4.0
+
+        What tox environments are ran during the tox invocation can be further filtered
+        via the operating system environment variable ``TOX_SKIP_ENV`` regular expression
+        (e.g. ``py27.*`` means **don't** evaluate environments that start with the key ``py27``).
+        Skipped environments will be logged at level two verbosity level.
+
 .. confval:: ignore_basepython_conflict=True|False(default)
 
     .. versionadded:: 3.1.0
diff --git a/src/tox/session.py b/src/tox/session.py
index 7da1efcd..dc25a277 100644
--- a/src/tox/session.py
+++ b/src/tox/session.py
@@ -381,7 +381,7 @@ class Session:
         self._spec2pkg = {}
         self._name2venv = {}
         try:
-            self.venvlist = [self.getvenv(x) for x in self.config.envlist]
+            self.venvlist = [self.getvenv(x) for x in self.evaluated_env_list()]
         except LookupError:
             raise SystemExit(1)
         except tox.exception.ConfigError as e:
@@ -389,6 +389,18 @@ class Session:
             raise SystemExit(1)
         self._actions = []
 
+    def evaluated_env_list(self):
+        tox_env_filter = os.environ.get("TOX_SKIP_ENV")
+        tox_env_filter_re = re.compile(tox_env_filter) if tox_env_filter is not None else None
+        for name in self.config.envlist:
+            if tox_env_filter_re is not None and tox_env_filter_re.match(name):
+                msg = "skip environment {}, matches filter {!r}".format(
+                    name, tox_env_filter_re.pattern
+                )
+                self.report.verbosity1(msg)
+                continue
+            yield name
+
     @property
     def hook(self):
         return self.config.pluginmanager.hook
diff --git a/src/tox/venv.py b/src/tox/venv.py
index a10149a9..0209f915 100755
--- a/src/tox/venv.py
+++ b/src/tox/venv.py
@@ -5,6 +5,7 @@ import pipes
 import re
 import sys
 import warnings
+from itertools import chain
 
 import py
 
@@ -231,7 +232,7 @@ class VirtualEnv(object):
         setup_py = setupdir.join("setup.py")
         setup_cfg = setupdir.join("setup.cfg")
         args = [self.envconfig.envpython, str(setup_py), "--name"]
-        env = self._getenv()
+        env = self._get_os_environ()
         output = action.popen(args, cwd=setupdir, redirect=False, returnout=True, env=env)
         name = output.strip()
         args = [self.envconfig.envpython, "-c", "import sys; print(sys.path)"]
@@ -297,30 +298,26 @@ class VirtualEnv(object):
         return options
 
     def run_install_command(self, packages, action, options=()):
-        argv = self.envconfig.install_command[:]
-        i = argv.index("{packages}")
-        argv[i : i + 1] = packages
-        if "{opts}" in argv:
-            i = argv.index("{opts}")
-            argv[i : i + 1] = list(options)
+        def expand(val):
+            # expand an install command
+            if val == "{packages}":
+                for package in packages:
+                    yield package
+            elif val == "{opts}":
+                for opt in options:
+                    yield opt
+            else:
+                yield val
 
-        for x in ("PIP_RESPECT_VIRTUALENV", "PIP_REQUIRE_VIRTUALENV", "__PYVENV_LAUNCHER__"):
-            os.environ.pop(x, None)
+        cmd = list(chain.from_iterable(expand(val) for val in self.envconfig.install_command))
 
-        if "PYTHONPATH" not in self.envconfig.passenv:
-            # If PYTHONPATH not explicitly asked for, remove it.
-            if "PYTHONPATH" in os.environ:
-                self.session.report.warning(
-                    "Discarding $PYTHONPATH from environment, to override "
-                    "specify PYTHONPATH in 'passenv' in your configuration."
-                )
-                os.environ.pop("PYTHONPATH")
+        self.ensure_pip_os_environ_ok()
 
         old_stdout = sys.stdout
         sys.stdout = codecs.getwriter("utf8")(sys.stdout)
         try:
             self._pcall(
-                argv,
+                cmd,
                 cwd=self.envconfig.config.toxinidir,
                 action=action,
                 redirect=self.session.report.verbosity < 2,
@@ -328,6 +325,24 @@ class VirtualEnv(object):
         finally:
             sys.stdout = old_stdout
 
+    def ensure_pip_os_environ_ok(self):
+        for key in ("PIP_RESPECT_VIRTUALENV", "PIP_REQUIRE_VIRTUALENV", "__PYVENV_LAUNCHER__"):
+            os.environ.pop(key, None)
+        if "PYTHONPATH" not in self.envconfig.passenv:
+            # If PYTHONPATH not explicitly asked for, remove it.
+            if "PYTHONPATH" in os.environ:
+                self.session.report.warning(
+                    "Discarding $PYTHONPATH from environment, to override "
+                    "specify PYTHONPATH in 'passenv' in your configuration."
+                )
+                os.environ.pop("PYTHONPATH")
+
+        # installing packages at user level may mean we're not installing inside the venv
+        os.environ["PIP_USER"] = "0"
+
+        # installing without dependencies may lead to broken packages
+        os.environ["PIP_NO_DEPS"] = "0"
+
     def _install(self, deps, extraopts=None, action=None):
         if not deps:
             return
@@ -353,13 +368,13 @@ class VirtualEnv(object):
                 options.extend(extraopts)
             self.run_install_command(packages=packages, options=options, action=action)
 
-    def _getenv(self, testcommand=False):
-        if testcommand:
+    def _get_os_environ(self, is_test_command=False):
+        if is_test_command:
             # for executing tests we construct a clean environment
             env = {}
-            for envname in self.envconfig.passenv:
-                if envname in os.environ:
-                    env[envname] = os.environ[envname]
+            for env_key in self.envconfig.passenv:
+                if env_key in os.environ:
+                    env[env_key] = os.environ[env_key]
         else:
             # for executing non-test commands we use the full
             # invocation environment
@@ -377,7 +392,7 @@ class VirtualEnv(object):
             self.session.make_emptydir(self.envconfig.envtmpdir)
             self.envconfig.envtmpdir.ensure(dir=1)
             cwd = self.envconfig.changedir
-            env = self._getenv(testcommand=True)
+            env = self._get_os_environ(is_test_command=True)
             # Display PYTHONHASHSEED to assist with reproducibility.
             action.setactivity("runtests", "PYTHONHASHSEED={!r}".format(env.get("PYTHONHASHSEED")))
             for i, argv in enumerate(self.envconfig.commands):
@@ -405,7 +420,7 @@ class VirtualEnv(object):
                         action=action,
                         redirect=redirect,
                         ignore_ret=ignore_ret,
-                        testcommand=True,
+                        is_test_command=True,
                     )
                 except tox.exception.InvocationError as err:
                     if self.envconfig.ignore_outcome:
@@ -424,18 +439,28 @@ class VirtualEnv(object):
                     raise
 
     def _pcall(
-        self, args, cwd, venv=True, testcommand=False, action=None, redirect=True, ignore_ret=False
+        self,
+        args,
+        cwd,
+        venv=True,
+        is_test_command=False,
+        action=None,
+        redirect=True,
+        ignore_ret=False,
     ):
+        # construct environment variables
         os.environ.pop("VIRTUALENV_PYTHON", None)
+        env = self._get_os_environ(is_test_command=is_test_command)
+        bin_dir = str(self.envconfig.envbindir)
+        env["PATH"] = os.pathsep.join([bin_dir, os.environ["PATH"]])
+        self.session.report.verbosity2("setting PATH={}".format(env["PATH"]))
 
-        cwd.ensure(dir=1)
+        # get command
         args[0] = self.getcommandpath(args[0], venv, cwd)
         if sys.platform != "win32" and "TOX_LIMITED_SHEBANG" in os.environ:
             args = prepend_shebang_interpreter(args)
-        env = self._getenv(testcommand=testcommand)
-        bindir = str(self.envconfig.envbindir)
-        env["PATH"] = p = os.pathsep.join([bindir, os.environ["PATH"]])
-        self.session.report.verbosity2("setting PATH={}".format(p))
+
+        cwd.ensure(dir=1)  # ensure the cwd exists
         return action.popen(args, cwd=cwd, env=env, redirect=redirect, ignore_ret=ignore_ret)
 
 

bug: tox should run pip with PIP_USER=0
- [X] Minimal reproduceable example or detailed description, assign "bug"
- [X] OS and `pip list` output

tox cannot use pip to install in a venv if the user has a config file that defaults to --user installs (e.g. because they (I) intend to use the distro package manager when touching distro packages) -- because pip crashes in such settings.  By setting the PIP_USER environment variable to 0, tox could override that setting to force the use of in-venv installs.

Arch Linux Py3.6 (from distro) in a clean venv.
pip list
```
Package    Version
---------- -------
pip        9.0.3  
pluggy     0.6.0  
py         1.5.3  
setuptools 39.0.1 
six        1.11.0 
tox        3.0.0  
virtualenv 16.0.0
```
foo/setup.py
```
from setuptools import setup; setup(name="foo")
```
foo/tox.ini
```
[tox]
envlist = py36
```
~/.config/pip/pip.conf
```
[install]
user = true
```
Running tox yields
```
GLOB sdist-make: /tmp/foo/setup.py
py36 inst-nodeps: /tmp/foo/.tox/dist/foo-0.0.0.zip
ERROR: invocation failed (exit code 1), logfile: /tmp/foo/.tox/py36/log/py36-3.log
ERROR: actionid: py36
msg: installpkg
cmdargs: ['/tmp/foo/.tox/py36/bin/pip', 'install', '-U', '--no-deps', '/tmp/foo/.tox/dist/foo-0.0.0.zip']

Can not perform a '--user' install. User site-packages are not visible in this virtualenv.
Exception information:
Traceback (most recent call last):
  File "/tmp/foo/.tox/py36/lib/python3.6/site-packages/pip/_internal/basecommand.py", line 228, in main
    status = self.run(options, args)
  File "/tmp/foo/.tox/py36/lib/python3.6/site-packages/pip/_internal/commands/install.py", line 218, in run
    "Can not perform a '--user' install. User site-packages "
pip._internal.exceptions.InstallationError: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

py36 installed: foo==0.0.0
_____________________________________________________________________________________________ summary ______________________________________________________________________________________________
ERROR:   py36: InvocationError for command /tmp/foo/.tox/py36/bin/pip install -U --no-deps /tmp/foo/.tox/dist/foo-0.0.0.zip (see /tmp/foo/.tox/py36/log/py36-3.log) (exited with code 1)
```
diff --git a/tests/unit/session/test_session.py b/tests/unit/session/test_session.py
index 90b1b992..0e93f588 100644
--- a/tests/unit/session/test_session.py
+++ b/tests/unit/session/test_session.py
@@ -140,3 +140,73 @@ def test_skip_install_skip_package(cmd, initproj, mock_venv):
     )
     result = cmd("--notest")
     assert result.ret == 0
+
+
+@pytest.fixture()
+def venv_filter_project(initproj, cmd):
+    def func(*args):
+        initproj(
+            "pkg123-0.7",
+            filedefs={
+                "tox.ini": """
+                    [tox]
+                    envlist = {py27,py36}-{nocov,cov,diffcov}{,-extra}
+                    skipsdist = true
+
+                    [testenv]
+                    skip_install = true
+                    commands = python -c 'print("{envname}")'
+                """
+            },
+        )
+        result = cmd(*args)
+        assert result.ret == 0
+        active = [i.name for i in result.session.venvlist]
+        return active, result
+
+    yield func
+
+
+def test_venv_filter_empty_all_active(venv_filter_project, monkeypatch):
+    monkeypatch.delenv("TOX_SKIP_ENV", raising=False)
+    active, result = venv_filter_project("-a")
+    assert result.outlines == [
+        "py27-nocov",
+        "py27-nocov-extra",
+        "py27-cov",
+        "py27-cov-extra",
+        "py27-diffcov",
+        "py27-diffcov-extra",
+        "py36-nocov",
+        "py36-nocov-extra",
+        "py36-cov",
+        "py36-cov-extra",
+        "py36-diffcov",
+        "py36-diffcov-extra",
+    ]
+    assert active == result.outlines
+
+
+def test_venv_filter_match_all_none_active(venv_filter_project, monkeypatch):
+    monkeypatch.setenv("TOX_SKIP_ENV", ".*")
+    active, result = venv_filter_project("-a")
+    assert not active
+    existing_envs = result.outlines
+
+    _, result = venv_filter_project("-avv")
+    for name in existing_envs:
+        msg = "skip environment {}, matches filter '.*'".format(name)
+        assert msg in result.outlines
+
+
+def test_venv_filter_match_some_some_active(venv_filter_project, monkeypatch):
+    monkeypatch.setenv("TOX_SKIP_ENV", "py27.*")
+    active, result = venv_filter_project("-avvv")
+    assert active == [
+        "py36-nocov",
+        "py36-nocov-extra",
+        "py36-cov",
+        "py36-cov-extra",
+        "py36-diffcov",
+        "py36-diffcov-extra",
+    ]
diff --git a/tests/unit/test_venv.py b/tests/unit/test_venv.py
index 54a52511..5b830956 100644
--- a/tests/unit/test_venv.py
+++ b/tests/unit/test_venv.py
@@ -625,6 +625,8 @@ class TestVenvTest:
         assert "PIP_RESPECT_VIRTUALENV" not in os.environ
         assert "PIP_REQUIRE_VIRTUALENV" not in os.environ
         assert "__PYVENV_LAUNCHER__" not in os.environ
+        assert os.environ["PIP_USER"] == "0"
+        assert os.environ["PIP_NO_DEPS"] == "0"
 
     def test_pythonpath_usage(self, newmocksession, monkeypatch):
         monkeypatch.setenv("PYTHONPATH", "/my/awesome/library")

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-mock pytest-timeout pytest-xdist pytest-randomly
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
coverage==6.2
distlib==0.3.9
execnet==1.9.0
filelock==3.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
packaging==21.3
platformdirs==2.4.0
pluggy==0.13.1
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
pytest-mock==3.6.1
pytest-randomly==3.10.3
pytest-timeout==2.1.0
pytest-xdist==3.0.2
six==1.17.0
toml==0.10.2
tomli==1.2.3
-e git+https://github.com/tox-dev/tox.git@3b91d63c9c5a089ba8ae9cbaec20bdf52ecf25cf#egg=tox
typing_extensions==4.1.1
virtualenv==20.17.1
zipp==3.6.0

name: tox
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - coverage==6.2
      - distlib==0.3.9
      - execnet==1.9.0
      - filelock==3.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - packaging==21.3
      - platformdirs==2.4.0
      - pluggy==0.13.1
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytest-mock==3.6.1
      - pytest-randomly==3.10.3
      - pytest-timeout==2.1.0
      - pytest-xdist==3.0.2
      - six==1.17.0
      - toml==0.10.2
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - virtualenv==20.17.1
      - zipp==3.6.0
prefix: /opt/conda/envs/tox

tests/unit/session/test_session.py::test_venv_filter_match_some_some_active tests/unit/session/test_session.py::test_venv_filter_match_all_none_active
tests/unit/test_venv.py::TestCreationConfig::test_python_recreation tests/unit/test_venv.py::TestVenvTest::test_envbindir_path tests/unit/test_venv.py::TestVenvTest::test_pythonpath_usage tests/unit/test_venv.py::test_develop_extras tests/unit/test_venv.py::test_install_deps_pre tests/unit/test_venv.py::test_create tests/unit/test_venv.py::test_install_python3 tests/unit/test_venv.py::test_install_recreate tests/unit/test_venv.py::test_install_sdist_extras tests/unit/test_venv.py::test_install_deps_indexserver tests/unit/test_venv.py::test_installpkg_indexserver tests/unit/test_venv.py::test_install_deps_wildcard tests/unit/test_venv.py::test_install_command_verbosity[1-0] tests/unit/test_venv.py::test_env_variables_added_to_pcall tests/unit/test_venv.py::test_install_command_verbosity[0-0] tests/unit/test_venv.py::test_run_custom_install_command tests/unit/test_venv.py::test_install_command_verbosity[6-3] tests/unit/test_venv.py::test_install_command_verbosity[3-1] tests/unit/test_venv.py::test_installpkg_upgrade tests/unit/test_venv.py::test_install_command_verbosity[5-3] tests/unit/test_venv.py::test_install_command_verbosity[4-2] tests/unit/test_venv.py::test_install_command_verbosity[2-0] tests/unit/test_venv.py::test_installpkg_no_upgrade tests/unit/test_venv.py::test_run_install_command
tests/unit/session/test_session.py::test__resolve_pkg_doubledash tests/unit/session/test_session.py::test__resolve_pkg_with_alpha_version tests/unit/session/test_session.py::test__resolve_pkg_missing_directory_in_distshare tests/unit/session/test_session.py::test_tox_parallel_build_safe tests/unit/session/test_session.py::test_skip_sdist tests/unit/session/test_session.py::test__resolve_pkg_multiple_valid_versions tests/unit/session/test_session.py::test_venv_filter_empty_all_active tests/unit/session/test_session.py::test__resolve_pkg_with_invalid_version tests/unit/session/test_session.py::test_skip_install_skip_package tests/unit/session/test_session.py::test__resolve_pkg_missing_directory tests/unit/session/test_session.py::test_minversion tests/unit/test_venv.py::TestCreationConfig::test_develop_recreation tests/unit/test_venv.py::TestCreationConfig::test_dep_recreation tests/unit/test_venv.py::TestCreationConfig::test_matchingdependencies_latest tests/unit/test_venv.py::TestCreationConfig::test_basic tests/unit/test_venv.py::TestCreationConfig::test_matchingdependencies tests/unit/test_venv.py::TestCreationConfig::test_matchingdependencies_file tests/unit/test_venv.py::test_test_hashseed_is_in_output tests/unit/test_venv.py::test_env_variables_added_to_needs_reinstall tests/unit/test_venv.py::test_getdigest tests/unit/test_venv.py::test_install_command_not_installed tests/unit/test_venv.py::test_getsupportedinterpreter tests/unit/test_venv.py::test_install_error tests/unit/test_venv.py::test_install_command_not_installed_bash tests/unit/test_venv.py::test_install_command_whitelisted tests/unit/test_venv.py::test_commandpath_venv_precedence tests/unit/test_venv.py::test_create_sitepackages tests/unit/test_venv.py::test_test_runtests_action_command_is_in_output tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_empty_interpreter_ws tests/unit/test_venv.py::test_command_relative_issue36 tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_interpreter_args tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_empty_interpreter tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_interpreter_ws tests/unit/test_venv.py::test_tox_testenv_create tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_real tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_empty_instance tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_non_utf8 tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_interpreter_arg tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_long_example tests/unit/test_venv.py::test_tox_testenv_pre_post tests/unit/test_venv.py::test_tox_testenv_interpret_shebang_interpreter_simple tests/unit/test_venv.py::test_ignore_outcome_failing_cmd
doc/config.rst changelog/838.feature.rst src/tox/venv.py src/tox/session.py changelog/824.feature.rst
doc/config.rst changelog/838.feature.rst src/tox/venv.py src/tox/session.py changelog/824.feature.rst