Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.swift]
indent_style = space
indent_size = 4

[*.{yml,yaml}]
indent_style = space
indent_size = 2

[*.sh]
indent_style = space
indent_size = 2
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @luzanovdm
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Describe the user-visible or security-relevant outcome.
- [ ] I used only synthetic fixtures and examples.
- [ ] I did not add logging, clipboard access, or temporary plaintext files.
- [ ] I reviewed subprocess, identity, and atomic-write behavior if this change touches them.
- [ ] I updated `CHANGELOG.md` for a user-visible change, or no entry is needed.

## Screenshots

Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: macos-26
Expand All @@ -17,9 +21,11 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
persist-credentials: false

- name: Install test dependencies
run: brew install actionlint age ripgrep shellcheck sops xcodegen
run: brew bundle --file=Brewfile

- name: Check shell scripts
run: shellcheck Scripts/*.sh
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CodeQL

on:
release:
types:
- published

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze Swift
runs-on: macos-26
timeout-minutes: 30
permissions:
contents: read
security-events: write

steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
persist-credentials: false

- name: Install build dependencies
run: brew bundle --file=Brewfile

- name: Generate Xcode project
run: xcodegen generate

- name: Initialize CodeQL
uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4
with:
languages: swift
build-mode: manual

- name: Build for analysis
run: >-
xcodebuild build
-quiet
-project Cipherleaf.xcodeproj
-scheme Cipherleaf
-destination 'platform=macOS'
-derivedDataPath .build/CodeQLDerivedData
CODE_SIGNING_ALLOWED=NO

- name: Analyze
uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4
6 changes: 6 additions & 0 deletions Brewfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
brew "actionlint"
brew "age"
brew "ripgrep"
brew "shellcheck"
brew "sops"
brew "xcodegen"
124 changes: 117 additions & 7 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,120 @@
# Code of conduct
# Contributor Covenant 3.0 Code of Conduct

Be respectful, specific, and constructive.
## Our Pledge

Harassment, discrimination, personal attacks, and publication of another
person's private information are not acceptable. Project maintainers may edit
or remove contributions and restrict participation when necessary to keep the
community safe and productive.
We pledge to make our community welcoming, safe, and equitable for all.

Report conduct concerns privately to the maintainers.
We are committed to fostering an environment that respects and promotes the
dignity, rights, and contributions of all individuals, regardless of
characteristics including race, ethnicity, caste, color, age, physical
characteristics, neurodiversity, disability, sex or gender, gender identity or
expression, sexual orientation, language, philosophy or religion, national or
social origin, socio-economic position, level of education, or other status.
The same privileges of participation are extended to everyone who participates
in good faith and in accordance with this Covenant.

## Encouraged Behaviors

While acknowledging differences in social norms, we all strive to meet our
community's expectations for positive behavior. We also understand that our
words and actions may be interpreted differently than we intend based on
culture, background, or native language.

With these considerations in mind, we agree to behave mindfully toward each
other and act in ways that center our shared values, including:

1. Respecting the **purpose of our community**, our activities, and our ways of
gathering.
2. Engaging **kindly and honestly** with others.
3. Respecting **different viewpoints** and experiences.
4. **Taking responsibility** for our actions and contributions.
5. Gracefully giving and accepting **constructive feedback**.
6. Committing to **repairing harm** when it occurs.
7. Behaving in other ways that promote and sustain the **well-being of our
community**.

## Restricted Behaviors

We agree to restrict the following behaviors in our community. Instances,
threats, and promotion of these behaviors are violations of this Code of
Conduct.

1. **Harassment.** Violating explicitly expressed boundaries or engaging in
unnecessary personal attention after any clear request to stop.
2. **Character attacks.** Making insulting, demeaning, or pejorative comments
directed at a community member or group of people.
3. **Stereotyping or discrimination.** Characterizing anyone's personality or
behavior on the basis of immutable identities or traits.
4. **Sexualization.** Behaving in a way that would generally be considered
inappropriately intimate in the context or purpose of the community.
5. **Violating confidentiality.** Sharing or acting on someone's personal or
private information without their permission.
6. **Endangerment.** Causing, encouraging, or threatening violence or other
harm toward any person or group.
7. Behaving in other ways that **threaten the well-being** of our community.

### Other Restrictions

1. **Misleading identity.** Impersonating someone else for any reason, or
pretending to be someone else to evade enforcement actions.
2. **Failing to credit sources.** Not properly crediting the sources of content
you contribute.
3. **Promotional materials.** Sharing marketing or other commercial content in
a way that is outside the norms of the community.
4. **Irresponsible communication.** Failing to responsibly present content
which includes, links or describes any other restricted behaviors.

## Reporting an Issue

Tensions can occur between community members even when they are trying their
best to collaborate. Not every conflict represents a code of conduct violation,
and this Code of Conduct reinforces encouraged behaviors and norms that can
help avoid conflicts and minimize harm.

When an incident does occur, report it promptly and privately by emailing
[luzanov.dm@gmail.com](mailto:luzanov.dm@gmail.com). Include links or other
context that can help investigate the report. Do not open a public issue.

The maintainer will take reports seriously and make every effort to respond in
a timely manner. Reports will be investigated using the available messages,
logs, recordings, or witness accounts. Investigations and enforcement actions
will remain as transparent as practical while prioritizing safety and
confidentiality. Enforcement actions are handled privately with the involved
parties, though communicating a mutually agreed resolution to the community
may be appropriate.

## Addressing and Repairing Harm

If an investigation finds that this Code of Conduct has been violated, the
following enforcement ladder may be used based on the incident's impact.
Depending on severity, lower steps may be skipped.

1. **Warning.** A private written warning for a violation, with expectations
for repair such as an apology, acknowledgement of responsibility, or
clarification of expectations.
2. **Temporarily limited activities.** A time-limited cooldown after a repeated
or more serious violation. Limits may apply to particular channels or
interactions.
3. **Temporary suspension.** A suspension with written conditions for return
after repeated violations or a single serious violation.
4. **Permanent ban.** Removal from community spaces when other steps have
failed or a violation makes continued participation unsafe.

This ladder is a guideline and does not prevent the maintainer from using
reasonable discretion in the community's best interests.

## Scope

This Code of Conduct applies within all community spaces and when an individual
is officially representing the community in public or other spaces.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant, version
3.0](https://www.contributor-covenant.org/version/3/0/).

Contributor Covenant is stewarded by the Organization for Ethical Source and
licensed under [CC BY-SA
4.0](https://creativecommons.org/licenses/by-sa/4.0/). The enforcement ladder
was inspired by the work of [Mozilla's code of conduct
team](https://github.com/mozilla/inclusion).
41 changes: 39 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,42 @@
Issues and pull requests are welcome. Use synthetic data in every public
artifact.

## Before you start

Search existing issues and pull requests before opening a new one. Small bug
fixes and documentation improvements can go directly to a pull request. Open
an issue before substantial user-interface, security-model, or architecture
changes so the scope can be agreed before implementation.

Report suspected vulnerabilities through the private process in
[SECURITY.md](SECURITY.md), never in a public issue.

## Contribution workflow

1. Fork the repository and create a focused branch from the latest `main`.
2. Make the smallest coherent change and add or update tests where behavior
changes.
3. Run all validation commands below.
4. Open a pull request and complete the template.

The protected `main` branch accepts changes through pull requests with passing
CI. Maintainers squash-merge accepted changes so each pull request becomes one
signed, reviewable commit.

## Setup

Install Xcode 26 or newer, then:

```sh
brew install actionlint age ripgrep shellcheck sops xcodegen
brew bundle
Scripts/test.sh
shellcheck Scripts/*.sh
actionlint .github/workflows/*.yml
```

`Brewfile` is the source of truth for command-line development dependencies.
Use `brew bundle check` to confirm that they are already installed.

The generated Xcode project is not committed. Change `project.yml`, regenerate
with XcodeGen, and include project-generation coverage in local validation.

Expand Down Expand Up @@ -60,4 +85,16 @@ encrypted manifest unless all of its public metadata is intentionally public.

Keep pull requests focused. Explain the user-visible outcome, security
properties affected, and validation performed. UI changes should include a
screenshot made with synthetic values.
screenshot made with synthetic values. Update `CHANGELOG.md` when a change is
visible to users or affects release, compatibility, or security behavior.

Review feedback is part of the contribution: keep the branch current, answer
questions, and avoid unrelated cleanup in the same pull request. Generated
Xcode projects, build products, signing material, real identities, and real
encrypted documents must not be committed.

## Licensing

Cipherleaf does not require a contributor license agreement. By submitting a
contribution, you agree that it is licensed under the repository's
[MIT License](LICENSE).
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Cipherleaf

[![CI](https://github.com/luzanovdm/cipherleaf/actions/workflows/ci.yml/badge.svg)](https://github.com/luzanovdm/cipherleaf/actions/workflows/ci.yml)
[![CodeQL](https://github.com/luzanovdm/cipherleaf/actions/workflows/codeql.yml/badge.svg)](https://github.com/luzanovdm/cipherleaf/actions/workflows/codeql.yml)

Cipherleaf is a native macOS editor for existing
[SOPS](https://github.com/getsops/sops) documents encrypted with native
[age](https://github.com/FiloSottile/age) recipients.
Expand Down Expand Up @@ -58,9 +61,9 @@ brew install age sops
## Run from source

```sh
brew install xcodegen
git clone https://github.com/luzanovdm/cipherleaf.git
cd cipherleaf
brew bundle
xcodegen generate
open Cipherleaf.xcodeproj
```
Expand Down Expand Up @@ -92,12 +95,15 @@ application fits your threat model.
## Development

```sh
brew install actionlint age ripgrep shellcheck sops xcodegen
brew bundle
Scripts/test.sh
shellcheck Scripts/*.sh
actionlint .github/workflows/*.yml
```

The repository `Brewfile` is the source of truth for command-line development
and CI dependencies. Run `brew bundle check` to verify an existing setup.

`Scripts/test.sh` runs architecture and security guardrails, strict
`swift-format` linting, unit tests, and synthetic SOPS/age integration tests.
CI also lints shell scripts and workflows, builds an unsigned review package,
Expand Down
20 changes: 16 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@

Please do not open a public issue for a suspected vulnerability.

Use GitHub's private vulnerability reporting feature for this repository.
Include the affected version, a minimal reproduction, and the expected impact.
Do not include real secret values or private age identities.
Use [GitHub's private vulnerability reporting
form](https://github.com/luzanovdm/cipherleaf/security/advisories/new). Include
the affected version, a minimal reproduction, and the expected impact. Do not
include real secret values or private age identities.

Test only with synthetic data and systems you own or are authorized to use.
Please allow time for investigation and a coordinated fix before public
disclosure.

## Supported versions

Security fixes are applied to the latest release and the default branch.
| Version | Supported |
| --- | --- |
| Latest release | Yes |
| `main` | Yes, as unreleased development code |
| Older releases | No |

This is a small, volunteer-maintained project. Reports are handled on a
best-effort basis; there is no response-time guarantee or bug bounty program.

## Operational guidance

Expand Down