{"id":50249174,"url":"https://github.com/davidmalko87/jira-confluence-full-instance-backup","last_synced_at":"2026-05-27T01:00:53.656Z","repository":{"id":360557045,"uuid":"1250402565","full_name":"davidmalko87/jira-confluence-full-instance-backup","owner":"davidmalko87","description":"Automated full-instance backup for Jira \u0026 Confluence Cloud (Standard plan). Jenkins + CLI/menu; encrypted 7-Zip archives to GCS, S3, Azure or local; notify via Slack, Teams, email or webhook.","archived":false,"fork":false,"pushed_at":"2026-05-27T00:11:41.000Z","size":187,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-27T00:14:00.938Z","etag":null,"topics":["7zip","atlassian","atlassian-cloud","automation","azure","backup","cli","confluence","devops","disaster-recovery","gcs","jenkins","jira","python","s3","sre"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidmalko87.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-26T15:40:26.000Z","updated_at":"2026-05-27T00:11:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/davidmalko87/jira-confluence-full-instance-backup","commit_stats":null,"previous_names":["davidmalko87/jira-confluence-full-instance-backup"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/davidmalko87/jira-confluence-full-instance-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmalko87%2Fjira-confluence-full-instance-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmalko87%2Fjira-confluence-full-instance-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmalko87%2Fjira-confluence-full-instance-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmalko87%2Fjira-confluence-full-instance-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidmalko87","download_url":"https://codeload.github.com/davidmalko87/jira-confluence-full-instance-backup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmalko87%2Fjira-confluence-full-instance-backup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33545458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["7zip","atlassian","atlassian-cloud","automation","azure","backup","cli","confluence","devops","disaster-recovery","gcs","jenkins","jira","python","s3","sre"],"created_at":"2026-05-27T01:00:33.067Z","updated_at":"2026-05-27T01:00:53.617Z","avatar_url":"https://github.com/davidmalko87.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jira \u0026 Confluence Full-Instance Backup\n\n[![CI](https://github.com/davidmalko87/jira-confluence-full-instance-backup/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/davidmalko87/jira-confluence-full-instance-backup/actions/workflows/ci.yml)\n[![PyPI version](https://img.shields.io/pypi/v/jira-confluence-full-instance-backup.svg?logo=pypi\u0026logoColor=white)](https://pypi.org/project/jira-confluence-full-instance-backup/)\n[![PyPI downloads](https://img.shields.io/pypi/dm/jira-confluence-full-instance-backup.svg)](https://pypi.org/project/jira-confluence-full-instance-backup/)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Python](https://img.shields.io/pypi/pyversions/jira-confluence-full-instance-backup.svg?logo=python\u0026logoColor=white)](https://pypi.org/project/jira-confluence-full-instance-backup/)\n[![Jira Cloud](https://img.shields.io/badge/Jira-Cloud-0052CC.svg?logo=jira\u0026logoColor=white)](https://www.atlassian.com/software/jira)\n[![Confluence Cloud](https://img.shields.io/badge/Confluence-Cloud-172B4D.svg?logo=confluence\u0026logoColor=white)](https://www.atlassian.com/software/confluence)\n[![Storage](https://img.shields.io/badge/storage-GCS%20%7C%20S3%20%7C%20Azure%20%7C%20local-success.svg)](#storage-backends)\n[![Notify](https://img.shields.io/badge/notify-Chat%20%7C%20Slack%20%7C%20Teams%20%7C%20email%20%7C%20webhook-success.svg)](#notification-channels)\n[![Last commit](https://img.shields.io/github/last-commit/davidmalko87/jira-confluence-full-instance-backup.svg)](https://github.com/davidmalko87/jira-confluence-full-instance-backup/commits/master)\n\nAutomated **full-instance backup** of **Jira Cloud** and **Confluence Cloud** for\nthe Atlassian **Standard plan**. Run it by hand from an interactive menu, or\nunattended from Jenkins/cron. Backups are encrypted and shipped to **the cloud\nof your choice** — Google Cloud Storage, AWS S3 (and S3-compatible stores),\nAzure Blob, or a local/mounted directory — with notifications to **any channel**\nyou use: Slack, Microsoft Teams, Discord, Google Chat, email, or a generic\nwebhook.\n\n---\n\n## Why?\n\nOn **March 30, 2026**, Atlassian [deprecated the Backup Manager API](https://community.atlassian.com/forums/Jira-questions/Backup-Manager-API-deprecation-is-there-going-to-be-a/qaq-p/3120079) for Jira Cloud. Direct API-token calls to the backup endpoint now return:\n\n```\nHTTP 403\n{\"error\":\"This feature is only accessible from the UI.\"}\n```\n\nThe replacement [v2 Backup \u0026 Restore API](https://developer.atlassian.com/cloud/admin/backup/) is Premium/Enterprise only, leaving Standard-plan customers with no automation path for full-instance backup — only the manual UI button. This tool restores that automation by **replaying the browser UI session** for Jira, while Confluence uses the OBM REST API (which still accepts API tokens). Both flow into one pipeline that archives, encrypts, uploads, and notifies.\n\nFor per-project Jira backup/restore, see the sibling project [`jira-project-backup-restore`](https://github.com/davidmalko87/jira-project-backup-restore).\n\n---\n\n## Features\n\n| Feature | Description |\n|---|---|\n| **Full-instance backup** | Jira (all projects, attachments, avatars, logos) + Confluence (all spaces, attachments) in one run |\n| **Run anywhere** | Interactive **menu** for VMs/manual use **and** **CLI flags** for Jenkins/cron — same codebase; the `Jenkinsfile` runs on **Linux and Windows** agents |\n| **One-paste Jenkins setup** | Export a Script Console script from your config that creates all credentials + the pipeline job — no manual credential forms |\n| **Pluggable storage** | **GCS · AWS S3 / S3-compatible (R2, B2, MinIO, Spaces) · Azure Blob · local** — pick one flag; only that SDK is needed |\n| **Pluggable notifications** | **Slack · Teams · Discord · Google Chat · email (SMTP) · generic webhook** — any combination, no extra deps |\n| **Optional encryption** | 7-Zip AES-256 with encrypted headers — on by default, switch off with `--no-encrypt` |\n| **Configurable compression** | `0` (store) … `9` (ultra) |\n| **Custom filenames** | Name templates: `{product} {site} {date} {time} {datetime} {timestamp}` |\n| **Integrity \u0026 housekeeping** | `manifest.json` with sha256 + `--validate`, `--cleanup`, `--skip-existing`, `--dry-run` |\n| **Cooldown-aware** | Atlassian's 48h throttle (HTTP 412) is detected and skipped cleanly — no false failures |\n| **Connection test** | Validates Jira cookies + Confluence token, warns when the Jira session is near expiry |\n\n---\n\n## Install\n\n```bash\npip install jira-confluence-full-instance-backup            # core (requests)\n# add the storage backend you use:\npip install \"jira-confluence-full-instance-backup[s3]\"      # or [gcs] / [azure]\n# optional nicer interactive output (progress bars, color):\npip install \"jira-confluence-full-instance-backup[ui]\"\n# everything:\npip install \"jira-confluence-full-instance-backup[all]\"\n```\n\nOr from source:\n\n```bash\ngit clone https://github.com/davidmalko87/jira-confluence-full-instance-backup.git\ncd jira-confluence-full-instance-backup\npip install -r requirements.txt          # + requirements-\u003cprovider\u003e.txt as needed\n```\n\nRequirements: Python 3.10+, and `7z` on PATH (`apt install p7zip-full`, or set `SEVEN_ZIP_PATH`).\n\n---\n\n## Quick Start\n\n### 1. Configure\n\n```bash\ncp .env.example .env      # fill in real values — .env is gitignored\n```\n\nOr use the guided menu (writes `.env` for you): `jira-confluence-backup` → **Configure credentials**.\nIt explains every field — including how to obtain the Jira cookie blob — and validates what you paste.\n\n\u003e **Hidden input is intentional.** When entering secrets (API token, cookie blob, passwords),\n\u003e nothing is echoed to the screen — the prompt shows `[input hidden — paste, then Enter]`. Paste\n\u003e and press Enter; the tool confirms back (e.g. *\"captured 5 cookie(s); all required present\"*) so\n\u003e you know it registered, without ever displaying the value. Use **Test connections** to verify.\n\n### 2. Run — interactive menu\n\n```bash\njira-confluence-backup            # or: python main.py   /   python -m backup\n```\n\n```\n=== Atlassian Full-Instance Backup ===\n  Jira     https://\u003cyour-site\u003e.atlassian.net\n  Storage  s3:my-backups\n  Notify   slack\n\n  1) Backup Jira          7) Validate backup\n  2) Backup Confluence    8) Cleanup backups\n  3) Backup both          9) Test connections\n  4) Full run            10) Configure credentials\n  5) Archive ./out       11) Show configuration\n  6) Upload ./archive    12) List local backups\n                         13) Export Jenkins setup\n                         14) Refresh Jira cookies\n  0) Exit\n```\n\n### 3. Run — CLI (automation)\n\n```bash\njira-confluence-backup --all                              # backup both -\u003e archive -\u003e upload -\u003e notify\njira-confluence-backup --all --dry-run                    # preview only, no API calls / no cooldown burn\njira-confluence-backup --backup jira,confluence --archive --upload --notify\njira-confluence-backup --validate                         # check the archive against its manifest\njira-confluence-backup --cleanup --keep-days 28           # prune incomplete + old local backups\njira-confluence-backup --test-connection                  # exit 0 if both auth paths are OK\n```\n\n\u003e Output is plain ASCII (`[INFO]/[OK]`) by default — safe on any console, including legacy Windows. Install the `ui` extra for colored output and progress bars.\n\n---\n\n## How It Works\n\n```\nSetup  -\u003e  Jira  -\u003e  Confluence  -\u003e  Archive  -\u003e  Upload          -\u003e  Notify\n(venv)    (cookies)  (API token)    (7z, opt.    (\u003cprovider\u003e://      (your\n                                     AES-256)     \u003cdest\u003e/Y/M/D/)      channels)\n```\n\nStages are independent: a Jira cookie expiry does not stop the Confluence stage.\n\n### Auth model\n\n| Product | Endpoint | Auth | Why |\n|---|---|---|---|\n| Jira | `/rest/backup/1/export/runbackup` | **Session cookies + UI headers** | Atlassian gates this endpoint to UI sessions only — API tokens return 403 |\n| Confluence | `/wiki/rest/obm/1.0/runbackup` | **Basic** (email + API token) | OBM never received the UI-only lockdown |\n\n\u003e **Do not replace the Jira side with an API token** — it is gated to browser\n\u003e sessions and returns `403 \"This feature is only accessible from the UI.\"`.\n\u003e One dedicated Atlassian **admin account** supplies both: its API token (for\n\u003e Confluence) and its browser session cookies (for Jira).\n\n---\n\n## Storage backends\n\nSet `STORAGE_PROVIDER` + `STORAGE_DEST` (or `--provider` / `--dest`). Only the chosen SDK is imported; a missing one prints a `pip install` hint.\n\n| Provider | `STORAGE_DEST` | Optional SDK | Credentials |\n|---|---|---|---|\n| `gcs` | bucket | `requirements-gcs.txt` | `GOOGLE_APPLICATION_CREDENTIALS` (SA JSON) |\n| `s3` | bucket | `requirements-s3.txt` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION` |\n| `azure` | container | `requirements-azure.txt` | `AZURE_STORAGE_CONNECTION_STRING` |\n| `local` | directory | *(none)* | *(none)* |\n\n**S3-compatible stores** (Cloudflare R2, Backblaze B2, MinIO, DigitalOcean Spaces): use `s3` plus `S3_ENDPOINT_URL`. Objects are written to `\u003cdest\u003e/YYYY/MM/DD/`. Retention is the bucket's job (set a lifecycle rule); use a **write-only** identity where possible.\n\n---\n\n## Notification channels\n\n`NOTIFY_CHANNELS` is a comma list — pick any. One report is built and rendered per channel; a failed channel is logged but never blocks the rest.\n\n| Channel | Needs | Notes |\n|---|---|---|\n| `slack` / `discord` / `teams` / `google-chat` | `NOTIFY_WEBHOOK_URL` | platform-specific incoming webhook |\n| `email` | `SMTP_*` | stdlib SMTP; port 465 → SSL, else STARTTLS |\n| `webhook` | `NOTIFY_WEBHOOK_URL` | raw JSON POST (PagerDuty / Opsgenie / your API) |\n\n---\n\n## Archiving: encryption, compression, names\n\n- **Encryption** (default on): 7-Zip AES-256 with encrypted headers, password from `ARCHIVE_PASSWORD`. Turn it off with `--no-encrypt` or by leaving the password blank.\n- **Compression**: `ARCHIVE_COMPRESSION` / `--compression` `0`–`9`.\n- **Names**: `PRODUCT_NAME_TEMPLATE` (the per-product `.zip`) and `ARCHIVE_NAME_TEMPLATE` (the `.7z`). Tokens: `{product} {site} {date} {time} {datetime} {timestamp} {year} {month} {day}`. Defaults: `{product}-{date}` and `atlassian-backup-{date}`.\n\n## Integrity \u0026 housekeeping\n\nEach successful run writes a `manifest.json` (timestamp, products, per-file + archive **sha256**, `complete: true`, `encrypted`) next to the archive and uploads it too.\n\n- `--validate` — re-checksum the local archive against the manifest.\n- `--cleanup [--keep-days N]` — remove incomplete backups (no manifest) and, optionally, ones older than N days.\n- `--skip-existing` — skip a product already backed up today.\n- `--dry-run` — preview any flow without API calls, archiving, or uploads.\n\n---\n\n## Jenkins\n\nThe `Jenkinsfile` is **cross-platform** — it runs on both Linux (`sh`) and Windows (`powershell`) agents. The agent needs **Python 3.10+** and **7-Zip** (`apt install p7zip-full`, or install 7-Zip on Windows). It runs weekly (`cron('H 2 * * 4')`) and installs only the selected provider's SDK.\n\n\u003e 📖 **Full step-by-step guide (prerequisites, plugins, every credential, troubleshooting): [docs/JENKINS_SETUP.md](docs/JENKINS_SETUP.md).** The summary below is the quick version.\n\n### Fast setup — one paste (recommended)\n\n1. Configure locally: `python main.py` → **Configure credentials** (writes `.env`).\n2. Generate the setup script: `python main.py` → **Export Jenkins setup** (or `python main.py --export-jenkins`). This writes a gitignored `jenkins-setup.groovy`.\n3. In Jenkins: **Manage Jenkins → Script Console**, paste the file's contents, **Run**. It creates every credential (with the exact IDs) **and** the `atlassian-full-backup` pipeline job pointing at this repo.\n4. Open the job → **Build Now**, then **delete `jenkins-setup.groovy`** (it contains secrets).\n\n\u003e The job uses *Pipeline script from SCM*, so Jenkins reads the `Jenkinsfile` straight from the repo at build time — there is no Jenkinsfile to generate or maintain inside Jenkins, and updates flow automatically from the repo.\n\n### Manual setup\n\nEdit the `Jenkinsfile` `environment` block for your site / provider / channels:\n\n```groovy\nenvironment {\n    SITE_JIRA        = 'https://\u003cYOUR_SITE\u003e.atlassian.net'\n    SITE_CONFLUENCE  = 'https://\u003cYOUR_SITE\u003e.atlassian.net/wiki'\n    STORAGE_PROVIDER = 'gcs'            // gcs | s3 | azure | local\n    STORAGE_DEST     = '\u003cYOUR_BUCKET\u003e'\n    NOTIFY_CHANNELS  = 'slack'          // any comma list\n}\n```\n\nCreate a **Pipeline** job → *Pipeline script from SCM* → Git → this repo → `*/master` → Script Path `Jenkinsfile`, and add the credentials below (IDs **must match exactly** — the pipeline binds only the ones your config needs):\n\n| Credential ID | Kind | Used when |\n|---|---|---|\n| `jira-cookies` | Secret text | always (Jira) |\n| `atlassian-email`, `atlassian-api-token` | Secret text | always (Confluence) |\n| `archive-password` | Secret text | always (may be blank = unencrypted) |\n| `gcp-backup-sa-key` | Secret file | `STORAGE_PROVIDER=gcs` |\n| `aws-access-key-id`, `aws-secret-access-key` | Secret text | `STORAGE_PROVIDER=s3` |\n| `azure-storage-connection-string` | Secret text | `STORAGE_PROVIDER=azure` |\n| `notify-webhook-url` | Secret text | chat/webhook channels |\n| `smtp-host/from/to/user/password` | Secret text | `email` channel |\n\nNo secrets live in the repo — they stay in the Jenkins Credentials store.\n\n---\n\n## Cookie Refresh Procedure\n\nThe Jira `tenant.session.token` JWT expires roughly every 30 days. When it does, the Jira stage exits with code 2 (`Cookie auth rejected — cookies likely expired`). Refresh takes ~60 seconds:\n\n1. Log into Atlassian as the backup admin account.\n2. Open `https://\u003cyour-site\u003e.atlassian.net/secure/admin/CloudExport.jspa`.\n3. **F12 → Network**, reload the page, right-click the `CloudExport.jspa` request (or any `/rest/backup/1/export/...` request) → **Copy → Copy as cURL**.\n4. Paste the whole cURL into the menu's **Configure credentials** (it extracts the cookies), or into the `jira-cookies` Jenkins credential / `JIRA_COOKIES` in `.env`.\n\nThe cookie blob must contain at least `tenant.session.token` and `atlassian.xsrf.token`. Other cookies such as `JSESSIONID` / `AWSALB` / `AWSALBCORS` are load-balancer/servlet cookies that some instances set and others don't — they're forwarded automatically when present, and not required. Using a real request's \"Copy as cURL\" (rather than the Application→Cookies list) ensures any that *are* needed come along.\n\n`Test connections` warns you in advance when the token is within a few days of expiry.\n\n---\n\n## Response Code Semantics\n\n| Code | Meaning | Behavior |\n|---|---|---|\n| 200 | Backup queued / status returned | Continue polling |\n| 403 | Auth rejected (UI-only gate) | Exit 2 — refresh Jira cookies |\n| 412 | 48-hour cooldown active | Exit 0 + marker — stays green |\n| 400 | Body schema rejected | Investigate body (Atlassian schema change) |\n| 406 | Confluence cosmetic error | Ignore — backup actually started |\n\n---\n\n## Configuration Reference\n\nAll values come from environment variables, optionally loaded from `.env` (see `.env.example`). In Jenkins they are bound from the Credentials store at runtime — never from a file in the repo.\n\n| Env var | Purpose |\n|---|---|\n| `SITE_JIRA` / `SITE_CONFLUENCE` | Atlassian base URLs |\n| `JIRA_COOKIES` | Browser session cookie blob for Jira |\n| `ATL_EMAIL` / `ATL_TOKEN` | Confluence Basic auth |\n| `ARCHIVE_PASSWORD` | 7-Zip AES-256 passphrase (blank = unencrypted) |\n| `ARCHIVE_COMPRESSION` | 0–9 |\n| `PRODUCT_NAME_TEMPLATE` / `ARCHIVE_NAME_TEMPLATE` | Filename templates |\n| `STORAGE_PROVIDER` / `STORAGE_DEST` | Backend + bucket/container/dir (aligned **comma lists** for multiple targets, e.g. `gcs,s3` + `bucketA,bucketB`) |\n| `BACKUP_CRON` | Jenkins schedule (default `H 2 * * 4`) |\n| `PYTHON_BIN` | Jenkins agent Python path (blank = auto-detect; set if `python` isn't on the service PATH) |\n| `S3_ENDPOINT_URL` | S3-compatible endpoint (s3 only) |\n| `GOOGLE_APPLICATION_CREDENTIALS` / `AWS_*` / `AZURE_STORAGE_CONNECTION_STRING` | Provider credentials |\n| `NOTIFY_CHANNELS` | Comma list of channels |\n| `NOTIFY_WEBHOOK_URL` / `SMTP_*` | Notification delivery |\n\n---\n\n## Project Structure\n\n```\njira-confluence-full-instance-backup/\n├── main.py                   # Convenience shim (python main.py)\n├── Jenkinsfile               # Declarative pipeline (provider/channel driven)\n├── pyproject.toml            # Packaging + console script + ruff config\n├── .env.example              # Local-testing template (real .env is gitignored)\n├── requirements.txt          # Core (requests)\n├── requirements-{gcs,s3,azure,ui}.txt   # Optional extras\n├── docs/JENKINS_SETUP.md     # Full Jenkins setup guide\n└── backup/\n    ├── cli.py                # Dual-mode entrypoint (menu + CLI)\n    ├── jira.py               # Cookie-authenticated Jira backup\n    ├── confluence.py         # OBM Basic-auth Confluence backup\n    ├── archive.py            # 7-Zip (optional AES-256, configurable level)\n    ├── upload.py             # Multi-provider upload (gcs/s3/azure/local)\n    ├── notify.py             # Multi-channel notifier\n    ├── manifest.py           # manifest.json: completeness + sha256 integrity\n    ├── config.py             # Env/.env config + Configure-menu persistence\n    ├── jenkins_export.py     # Generate Script Console Groovy (creds + job)\n    ├── naming.py             # Filename templating\n    └── ui.py                 # Console UI (rich-optional, ASCII-safe)\n```\n\n---\n\n## Known Limitations\n\nThese are Atlassian platform constraints, not tool limitations:\n\n- **48h Jira cooldown** between full-instance backups (weekly cadence is fine).\n- **Cookie lifetime** ~30 days; monthly manual refresh required.\n- **Confluence Filestore retention** ~14 days (the tool downloads immediately, so this affects only the source file).\n- **No restore automation** — restoring a full-instance backup is manual via Atlassian's UI; for per-project restore use [`jira-project-backup-restore`](https://github.com/davidmalko87/jira-project-backup-restore).\n\n---\n\n## Troubleshooting\n\nRun **Test connections** (menu option 9) first — it pinpoints which of Jira /\nConfluence / storage is misconfigured. Common errors and fixes (403 vs the 204\n\"success\", cookie refresh, the 48-hour cooldown, storage permissions, Jenkins)\nare in **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)**.\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). In short: no secrets in the repo, keep\ncloud SDKs optional, ASCII-only console output, and test auth/backup changes\nagainst a non-prod Atlassian instance. **Do not** switch Jira to API-token auth\n(see [Auth model](#auth-model)).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Related\n\n* [`jira-project-backup-restore`](https://github.com/davidmalko87/jira-project-backup-restore) — per-project Jira Cloud backup/restore via REST API.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmalko87%2Fjira-confluence-full-instance-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidmalko87%2Fjira-confluence-full-instance-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmalko87%2Fjira-confluence-full-instance-backup/lists"}