lsmcheck 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. lsmcheck-0.1.0/.github/CODEOWNERS +3 -0
  2. lsmcheck-0.1.0/.github/dependabot.yml +16 -0
  3. lsmcheck-0.1.0/.github/workflows/ci.yml +59 -0
  4. lsmcheck-0.1.0/.github/workflows/codeql.yml +35 -0
  5. lsmcheck-0.1.0/.github/workflows/dependency-review.yml +22 -0
  6. lsmcheck-0.1.0/.github/workflows/release.yml +63 -0
  7. lsmcheck-0.1.0/.github/workflows/scorecard.yml +42 -0
  8. lsmcheck-0.1.0/.github/workflows/zizmor.yml +28 -0
  9. lsmcheck-0.1.0/.gitignore +11 -0
  10. lsmcheck-0.1.0/CHANGELOG.md +7 -0
  11. lsmcheck-0.1.0/CONTRIBUTING.md +19 -0
  12. lsmcheck-0.1.0/LICENSE +12 -0
  13. lsmcheck-0.1.0/Makefile +16 -0
  14. lsmcheck-0.1.0/PKG-INFO +62 -0
  15. lsmcheck-0.1.0/README.md +34 -0
  16. lsmcheck-0.1.0/SECURITY.md +6 -0
  17. lsmcheck-0.1.0/pyproject.toml +114 -0
  18. lsmcheck-0.1.0/src/lsmcheck/__init__.py +54 -0
  19. lsmcheck-0.1.0/src/lsmcheck/_proc.py +81 -0
  20. lsmcheck-0.1.0/src/lsmcheck/apparmor.py +129 -0
  21. lsmcheck-0.1.0/src/lsmcheck/attrs.py +76 -0
  22. lsmcheck-0.1.0/src/lsmcheck/errors.py +10 -0
  23. lsmcheck-0.1.0/src/lsmcheck/lockdown.py +50 -0
  24. lsmcheck-0.1.0/src/lsmcheck/lsms.py +147 -0
  25. lsmcheck-0.1.0/src/lsmcheck/py.typed +0 -0
  26. lsmcheck-0.1.0/src/lsmcheck/selinux.py +118 -0
  27. lsmcheck-0.1.0/src/lsmcheck/yama.py +46 -0
  28. lsmcheck-0.1.0/tests/__init__.py +1 -0
  29. lsmcheck-0.1.0/tests/test_apparmor.py +151 -0
  30. lsmcheck-0.1.0/tests/test_attrs.py +69 -0
  31. lsmcheck-0.1.0/tests/test_lockdown.py +52 -0
  32. lsmcheck-0.1.0/tests/test_lsmcheck.py +10 -0
  33. lsmcheck-0.1.0/tests/test_lsms.py +158 -0
  34. lsmcheck-0.1.0/tests/test_proc.py +96 -0
  35. lsmcheck-0.1.0/tests/test_selinux.py +131 -0
  36. lsmcheck-0.1.0/tests/test_yama.py +43 -0
  37. lsmcheck-0.1.0/uv.lock +760 -0
@@ -0,0 +1,3 @@
1
+ # SPDX-License-Identifier: 0BSD
2
+
3
+ * @Sudo-Ivan
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ cooldown:
8
+ default-days: 7
9
+ open-pull-requests-limit: 5
10
+ - package-ecosystem: uv
11
+ directory: /
12
+ schedule:
13
+ interval: weekly
14
+ cooldown:
15
+ default-days: 7
16
+ open-pull-requests-limit: 5
@@ -0,0 +1,59 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ schedule:
8
+ - cron: "9 7 * * 1"
9
+
10
+ permissions: {}
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
17
+ with:
18
+ egress-policy: audit
19
+
20
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ persist-credentials: false
23
+
24
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
25
+ with:
26
+ version: "0.11.32"
27
+ enable-cache: true
28
+
29
+ - run: uv sync --locked
30
+
31
+ - run: uv run ruff check .
32
+ - run: uv run ruff format --check .
33
+ - run: uv run bandit -r src/
34
+ - run: uv run mypy
35
+ - run: uvx ty check src tests
36
+
37
+ test:
38
+ runs-on: ubuntu-latest
39
+ strategy:
40
+ fail-fast: false
41
+ matrix:
42
+ python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
43
+ steps:
44
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
45
+ with:
46
+ egress-policy: audit
47
+
48
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
49
+ with:
50
+ persist-credentials: false
51
+
52
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
53
+ with:
54
+ version: "0.11.32"
55
+ enable-cache: true
56
+
57
+ - run: uv python install ${{ matrix.python }}
58
+ - run: uv sync --locked --python ${{ matrix.python }}
59
+ - run: uv run pytest --cov
@@ -0,0 +1,35 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ schedule:
8
+ - cron: "17 3 * * 4"
9
+
10
+ permissions: {}
11
+
12
+ jobs:
13
+ analyze:
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ actions: read
17
+ contents: read
18
+ security-events: write
19
+ steps:
20
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
21
+ with:
22
+ egress-policy: audit
23
+
24
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25
+ with:
26
+ persist-credentials: false
27
+
28
+ - uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
29
+ with:
30
+ languages: python
31
+ queries: security-and-quality
32
+
33
+ - uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
34
+ with:
35
+ category: "/language:python"
@@ -0,0 +1,22 @@
1
+ name: Dependency Review
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ permissions: {}
7
+
8
+ jobs:
9
+ dependency-review:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ steps:
14
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
15
+ with:
16
+ egress-policy: audit
17
+
18
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
19
+ with:
20
+ persist-credentials: false
21
+
22
+ - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
@@ -0,0 +1,63 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions: {}
8
+
9
+ jobs:
10
+ release:
11
+ runs-on: ubuntu-latest
12
+ environment:
13
+ name: pypi
14
+ url: https://pypi.org/p/lsmcheck
15
+ permissions:
16
+ contents: write
17
+ id-token: write
18
+ attestations: write
19
+ steps:
20
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
21
+ with:
22
+ egress-policy: audit
23
+
24
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25
+ with:
26
+ persist-credentials: false
27
+
28
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
29
+ with:
30
+ version: "0.11.32"
31
+
32
+ - run: uv sync --locked
33
+
34
+ - name: Verify tag matches package version
35
+ run: |
36
+ tag="${GITHUB_REF_NAME#v}"
37
+ version="$(uv run python -c 'import lsmcheck; print(lsmcheck.__version__)')"
38
+ if [ "$tag" != "$version" ]; then
39
+ echo "tag $tag does not match package version $version" >&2
40
+ exit 1
41
+ fi
42
+
43
+ - run: uv build
44
+
45
+ - name: Attest build provenance
46
+ uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
47
+ with:
48
+ subject-path: dist/*
49
+
50
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
51
+ with:
52
+ attestations: true
53
+
54
+ - name: Create GitHub release
55
+ env:
56
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
+ run: |
58
+ gh release create "${GITHUB_REF_NAME}" \
59
+ --repo "${GITHUB_REPOSITORY}" \
60
+ --verify-tag \
61
+ --title "${GITHUB_REF_NAME}" \
62
+ --generate-notes \
63
+ dist/*
@@ -0,0 +1,42 @@
1
+ name: OpenSSF Scorecard
2
+
3
+ on:
4
+ branch_protection_rule:
5
+ push:
6
+ branches: [master]
7
+ workflow_dispatch:
8
+ schedule:
9
+ - cron: "42 5 * * 6"
10
+
11
+ permissions: read-all
12
+
13
+ jobs:
14
+ analysis:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ security-events: write
18
+ id-token: write
19
+ steps:
20
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
21
+ with:
22
+ egress-policy: audit
23
+
24
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25
+ with:
26
+ persist-credentials: false
27
+
28
+ - uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
29
+ with:
30
+ results_file: results.sarif
31
+ results_format: sarif
32
+ publish_results: true
33
+
34
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
35
+ with:
36
+ name: SARIF file
37
+ path: results.sarif
38
+ retention-days: 5
39
+
40
+ - uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
41
+ with:
42
+ sarif_file: results.sarif
@@ -0,0 +1,28 @@
1
+ name: zizmor
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ paths: [.github/**]
7
+ pull_request:
8
+ paths: [.github/**]
9
+
10
+ permissions: {}
11
+
12
+ jobs:
13
+ zizmor:
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ security-events: write
17
+ steps:
18
+ - uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
19
+ with:
20
+ egress-policy: audit
21
+
22
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
+ with:
24
+ persist-credentials: false
25
+
26
+ - uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4
27
+ with:
28
+ advanced-security: false
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ .mypy_cache/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage*
11
+ htmlcov/
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - Unreleased
4
+
5
+ Initial release: LSM detection via /sys/kernel/security/lsm,
6
+ /proc/<pid>/attr reads and writes, and AppArmor, SELinux, Yama and
7
+ lockdown introspection.
@@ -0,0 +1,19 @@
1
+ # Contributing
2
+
3
+ Report bugs through GitHub issues. Security reports go to
4
+ security@quad4.io (see SECURITY.md).
5
+
6
+ ## Setup
7
+
8
+ uv sync
9
+ make check
10
+
11
+ `make check` runs the full local gate: ruff lint and format, bandit,
12
+ mypy strict, ty, and pytest with coverage.
13
+
14
+ ## Conventions
15
+
16
+ - No runtime dependencies unless the project genuinely needs one.
17
+ - Source files start with the SPDX license identifier.
18
+ - Public API changes need tests.
19
+ - Commit messages: short, imperative, formal.
lsmcheck-0.1.0/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2026 Quad4
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any purpose
4
+ with or without fee is hereby granted.
5
+
6
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
7
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
8
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
10
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
11
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
12
+ PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,16 @@
1
+ .PHONY: check lint test build
2
+
3
+ check: lint test
4
+
5
+ lint:
6
+ uv run ruff check .
7
+ uv run ruff format --check .
8
+ uv run bandit -r src/
9
+ uv run mypy
10
+ uvx ty check src tests
11
+
12
+ test:
13
+ uv run pytest --cov --cov-report=term-missing
14
+
15
+ build:
16
+ uv build
@@ -0,0 +1,62 @@
1
+ Metadata-Version: 2.5
2
+ Name: lsmcheck
3
+ Version: 0.1.0
4
+ Summary: Linux Security Module introspection
5
+ Project-URL: Homepage, https://quad4.io
6
+ Project-URL: Repository, https://github.com/Quad4-Software/lsmcheck
7
+ Project-URL: Issues, https://github.com/Quad4-Software/lsmcheck/issues
8
+ Project-URL: Changelog, https://github.com/Quad4-Software/lsmcheck/blob/master/CHANGELOG.md
9
+ Author: Quad4
10
+ License-Expression: 0BSD
11
+ License-File: LICENSE
12
+ Keywords: apparmor,linux,lsm,security,selinux
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: BSD License
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Security
24
+ Classifier: Topic :: System :: Operating System Kernels :: Linux
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+
29
+ # lsmcheck
30
+
31
+ [![CI](https://github.com/Quad4-Software/lsmcheck/actions/workflows/ci.yml/badge.svg)](https://github.com/Quad4-Software/lsmcheck/actions/workflows/ci.yml)
32
+ [![CodeQL](https://github.com/Quad4-Software/lsmcheck/actions/workflows/codeql.yml/badge.svg)](https://github.com/Quad4-Software/lsmcheck/actions/workflows/codeql.yml)
33
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Quad4-Software/lsmcheck/badge)](https://securityscorecards.dev/viewer/?uri=github.com/Quad4-Software/lsmcheck)
34
+ [![PyPI](https://img.shields.io/pypi/v/lsmcheck.svg)](https://pypi.org/project/lsmcheck/)
35
+ [![License: 0BSD](https://img.shields.io/badge/license-0BSD-blue)](LICENSE)
36
+
37
+ Linux Security Module introspection from procfs and sysfs only: which
38
+ LSMs the kernel runs, the security attributes of a process, and the
39
+ state of AppArmor, SELinux, Yama and lockdown. No dependencies, no
40
+ shell-outs; every reader degrades to None when the feature is absent.
41
+
42
+ Requires Python 3.10+ and Linux.
43
+
44
+ ## Install
45
+
46
+ pip install lsmcheck
47
+
48
+ ## Example
49
+
50
+ import lsmcheck
51
+
52
+ print(lsmcheck.active_lsms()) # [LSM.CAPABILITY, LSM.YAMA, ...]
53
+ ctx = lsmcheck.apparmor.current()
54
+ if ctx and ctx.mode == lsmcheck.apparmor.AppArmorMode.ENFORCE:
55
+ print("confined by", ctx.profile)
56
+
57
+ ## Development
58
+
59
+ uv sync --group dev
60
+ make check
61
+
62
+ License: 0BSD. Quad4 Software, https://quad4.io
@@ -0,0 +1,34 @@
1
+ # lsmcheck
2
+
3
+ [![CI](https://github.com/Quad4-Software/lsmcheck/actions/workflows/ci.yml/badge.svg)](https://github.com/Quad4-Software/lsmcheck/actions/workflows/ci.yml)
4
+ [![CodeQL](https://github.com/Quad4-Software/lsmcheck/actions/workflows/codeql.yml/badge.svg)](https://github.com/Quad4-Software/lsmcheck/actions/workflows/codeql.yml)
5
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Quad4-Software/lsmcheck/badge)](https://securityscorecards.dev/viewer/?uri=github.com/Quad4-Software/lsmcheck)
6
+ [![PyPI](https://img.shields.io/pypi/v/lsmcheck.svg)](https://pypi.org/project/lsmcheck/)
7
+ [![License: 0BSD](https://img.shields.io/badge/license-0BSD-blue)](LICENSE)
8
+
9
+ Linux Security Module introspection from procfs and sysfs only: which
10
+ LSMs the kernel runs, the security attributes of a process, and the
11
+ state of AppArmor, SELinux, Yama and lockdown. No dependencies, no
12
+ shell-outs; every reader degrades to None when the feature is absent.
13
+
14
+ Requires Python 3.10+ and Linux.
15
+
16
+ ## Install
17
+
18
+ pip install lsmcheck
19
+
20
+ ## Example
21
+
22
+ import lsmcheck
23
+
24
+ print(lsmcheck.active_lsms()) # [LSM.CAPABILITY, LSM.YAMA, ...]
25
+ ctx = lsmcheck.apparmor.current()
26
+ if ctx and ctx.mode == lsmcheck.apparmor.AppArmorMode.ENFORCE:
27
+ print("confined by", ctx.profile)
28
+
29
+ ## Development
30
+
31
+ uv sync --group dev
32
+ make check
33
+
34
+ License: 0BSD. Quad4 Software, https://quad4.io
@@ -0,0 +1,6 @@
1
+ # Security policy
2
+
3
+ Only the latest release is supported.
4
+
5
+ Report vulnerabilities to security@quad4.io. Do not open public issues for
6
+ security reports.
@@ -0,0 +1,114 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "lsmcheck"
7
+ dynamic = ["version"]
8
+ description = "Linux Security Module introspection"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "0BSD"
12
+ authors = [{ name = "Quad4" }]
13
+ keywords = ["lsm", "linux", "selinux", "apparmor", "security"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: BSD License",
18
+ "Operating System :: POSIX :: Linux",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Security",
26
+ "Topic :: System :: Operating System Kernels :: Linux",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = []
30
+
31
+ [project.urls]
32
+ Homepage = "https://quad4.io"
33
+ Repository = "https://github.com/Quad4-Software/lsmcheck"
34
+ Issues = "https://github.com/Quad4-Software/lsmcheck/issues"
35
+ Changelog = "https://github.com/Quad4-Software/lsmcheck/blob/master/CHANGELOG.md"
36
+
37
+ [tool.hatch.version]
38
+ path = "src/lsmcheck/__init__.py"
39
+
40
+ [dependency-groups]
41
+ dev = [
42
+ "pytest>=9.1.1",
43
+ "pytest-cov>=7.1.0",
44
+ "ruff>=0.16.8",
45
+ "bandit>=1.9.4",
46
+ "mypy>=2.3.1",
47
+ ]
48
+
49
+ [tool.ruff]
50
+ target-version = "py310"
51
+ src = ["src", "tests"]
52
+
53
+ [tool.ruff.lint]
54
+ select = [
55
+ "E", "W", # pycodestyle
56
+ "F", # pyflakes
57
+ "I", # isort
58
+ "N", # pep8-naming
59
+ "UP", # pyupgrade
60
+ "YTT", # sys.version misuse
61
+ "FA", # future annotations
62
+ "A", # builtins shadowing
63
+ "B", # flake8-bugbear
64
+ "BLE", # blind except
65
+ "C4", # comprehensions
66
+ "C90", # mccabe complexity
67
+ "DTZ", # timezone-aware datetimes
68
+ "ERA", # commented-out code
69
+ "FURB", # refurb
70
+ "G", # logging format
71
+ "ICN", # import conventions
72
+ "ISC", # implicit string concat
73
+ "LOG", # logging
74
+ "PERF", # perflint
75
+ "PGH", # pygrep hooks
76
+ "PIE", # misc lints
77
+ "PT", # pytest style
78
+ "PTH", # pathlib
79
+ "RET", # return
80
+ "RSE", # raise/return
81
+ "S", # bandit rules
82
+ "SIM", # simplify
83
+ "SLOT", # __slots__
84
+ "T20", # print
85
+ "TRY", # exception handling
86
+ "RUF", # ruff-specific
87
+ ]
88
+ ignore = [
89
+ "ISC001", # single-line implicit concat conflicts with the formatter
90
+ "TRY003", # long messages in raise calls are fine
91
+ ]
92
+
93
+ [tool.ruff.lint.per-file-ignores]
94
+ "tests/*" = ["S101", "S603"]
95
+
96
+ [tool.mypy]
97
+ strict = true
98
+ files = ["src", "tests"]
99
+
100
+ [tool.bandit]
101
+ exclude_dirs = ["tests"]
102
+
103
+ [tool.coverage.run]
104
+ branch = true
105
+ source = ["src/lsmcheck"]
106
+
107
+ [tool.coverage.report]
108
+ show_missing = true
109
+ fail_under = 80
110
+
111
+ [tool.pytest.ini_options]
112
+ testpaths = ["tests"]
113
+ xfail_strict = true
114
+ filterwarnings = ["error"]
@@ -0,0 +1,54 @@
1
+ # SPDX-License-Identifier: 0BSD
2
+ """Linux Security Module introspection.
3
+
4
+ Answers which LSMs are active on the running kernel and what they say
5
+ about a process, using only procfs and sysfs reads: no shell-outs, no C
6
+ libraries, no runtime dependencies. Every reader degrades gracefully
7
+ to None or an empty result when the kernel lacks the feature, so the
8
+ library is safe to call anywhere.
9
+
10
+ Kernel references: docs.kernel.org/admin-guide/LSM, proc_pid_attr(5).
11
+ """
12
+
13
+ from . import apparmor, lockdown, selinux, yama
14
+ from .attrs import (
15
+ ATTR_NAMES,
16
+ attr,
17
+ current,
18
+ exec_context,
19
+ prev,
20
+ set_attr,
21
+ set_exec_context,
22
+ )
23
+ from .errors import LsmError, UnsupportedError
24
+ from .lsms import (
25
+ LSM,
26
+ active_lsms,
27
+ is_active,
28
+ require_active,
29
+ securityfs_mounted,
30
+ )
31
+
32
+ __version__ = "0.1.0"
33
+
34
+ __all__ = [
35
+ "ATTR_NAMES",
36
+ "LSM",
37
+ "LsmError",
38
+ "UnsupportedError",
39
+ "__version__",
40
+ "active_lsms",
41
+ "apparmor",
42
+ "attr",
43
+ "current",
44
+ "exec_context",
45
+ "is_active",
46
+ "lockdown",
47
+ "prev",
48
+ "require_active",
49
+ "securityfs_mounted",
50
+ "selinux",
51
+ "set_attr",
52
+ "set_exec_context",
53
+ "yama",
54
+ ]