Phase 1 - Internal reference cleanup:
- Delete dev_docs/meetings/ (internal meeting notes/transcripts)
- Replace hardcoded usernames (padak/matejkys/dasa) with deploy/generic
- Replace "Internal AI Data Analyst" with "AI Data Analyst"
- Replace keboola/internal_ai_data_analyst URLs with your-org/ai-data-analyst
- Replace /tmp/keboola_load/ with /tmp/data_analyst_staging/ in dev_docs
Phase 2 - Deployment hardening:
- Tighten sudoers wildcards to explicit paths (visudo, sudoers cp)
- setup.sh creates all groups (data-ops, dataread, data-private) and deploy user
- webapp-setup.sh copies sudoers-webapp from repo instead of inline definition
- deploy.sh conditional copy for data_description.md (not in git for OSS)
- deploy.sh ownership changed to deploy:data-ops for /data/{scripts,docs,examples}
Phase 3 - Config and misc:
- Add ${ENV_VAR} interpolation to config/loader.py
- Expand config/instance.yaml.example with all sections (admins, deployment, auth, etc.)
- Create config/.env.template for secret values
- Add MIT LICENSE
- Fix .gitignore: add .venv/, docs/data_description.md
- Fix README.md: CSV status Planned, remove metrics/, update license text
- Translate Czech comments in requirements.txt to English
- Fix test_account_service.py: mock username mapping instead of relying on instance config
All 118 tests pass.
166 lines
11 KiB
Text
166 lines
11 KiB
Text
# Sudoers configuration for deploy user (Debian 12)
|
|
# Install with: sudo cp /opt/data-analyst/repo/server/sudoers-deploy /etc/sudoers.d/deploy
|
|
# Validate with: sudo visudo -cf /etc/sudoers.d/deploy
|
|
#
|
|
# Note: On Debian 12, core utils are in /usr/bin/ (not /bin/)
|
|
|
|
# Allow deploy user to manage server scripts
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/bin/* /usr/local/bin/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 755 /usr/local/bin/*
|
|
|
|
# Allow deploy user to manage sudoers files (explicit paths, no wildcards)
|
|
deploy ALL=(ALL) NOPASSWD: /usr/sbin/visudo -cf /opt/data-analyst/repo/server/sudoers-deploy
|
|
deploy ALL=(ALL) NOPASSWD: /usr/sbin/visudo -cf /opt/data-analyst/repo/server/sudoers-webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/sudoers-deploy /etc/sudoers.d/deploy
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/sudoers-webapp /etc/sudoers.d/webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 440 /etc/sudoers.d/deploy
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 440 /etc/sudoers.d/webapp
|
|
|
|
# Allow deploy user to manage application directory permissions
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown -R root\:data-ops /opt/data-analyst
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown root\:data-ops /opt/data-analyst/repo/.env
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R 770 /opt/data-analyst
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R g+s /opt/data-analyst
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 640 /opt/data-analyst/repo/.env
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/tee /opt/data-analyst/repo/.env
|
|
|
|
# Allow deploy user to manage webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/webapp.service /etc/systemd/system/webapp.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl status webapp
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-active webapp
|
|
|
|
# Allow deploy user to manage nginx
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx
|
|
|
|
# Allow deploy user to write webapp env file
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/tee /opt/data-analyst/.env
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown root\:data-ops /opt/data-analyst/.env
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 640 /opt/data-analyst/.env
|
|
|
|
# Allow deploy user to manage scripts in /data/scripts
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/scripts
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/scripts/* /data/scripts/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R 755 /data/scripts
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown -R deploy\:data-ops /data/scripts
|
|
|
|
# Allow deploy user to manage documentation in /data/docs
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/docs
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/docs/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/docs/* /data/docs/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp -r /opt/data-analyst/repo/docs/* /data/docs/
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R 775 /data/docs
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown -R deploy\:data-ops /data/docs
|
|
|
|
# Allow deploy user to manage notifications directory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/notifications
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown deploy\:data-ops /data/notifications
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 2770 /data/notifications
|
|
|
|
# Allow deploy user to manage notify-bot service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/notify-bot.service /etc/systemd/system/notify-bot.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl daemon-reload
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart notify-bot
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start notify-bot
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop notify-bot
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable notify-bot
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-active notify-bot
|
|
|
|
# Allow deploy (notify-bot) to list/run notification scripts as dataread group members only
|
|
# Used by /status "Run" button in Telegram via notify-scripts helper
|
|
deploy ALL=(%dataread) NOPASSWD: /usr/local/bin/notify-scripts
|
|
|
|
# Allow deploy user to manage ws-gateway service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/ws-gateway.service /etc/systemd/system/ws-gateway.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart ws-gateway
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start ws-gateway
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop ws-gateway
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable ws-gateway
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-active ws-gateway
|
|
|
|
# Allow deploy user to manage limits configuration
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/limits-users.conf /etc/security/limits.d/99-users.conf
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 644 /etc/security/limits.d/99-users.conf
|
|
|
|
# Allow deploy user to manage example notification scripts
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/examples/notifications
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/examples/notifications/* /data/examples/notifications/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R 755 /data/examples
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown -R deploy\:data-ops /data/examples
|
|
|
|
# Allow deploy user to manage Jira data directory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/src_data/raw/jira/*
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown -R root\:data-ops /data/src_data/raw/jira
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod -R 2770 /data/src_data/raw/jira
|
|
|
|
# Allow deploy user to manage password auth directory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/auth
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown www-data\:data-ops /data/auth
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 2770 /data/auth
|
|
|
|
# Allow deploy user to manage corporate memory directory and service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/corporate-memory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown deploy\:data-ops /data/corporate-memory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 2770 /data/corporate-memory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/corporate-memory.service /etc/systemd/system/corporate-memory.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/corporate-memory.timer /etc/systemd/system/corporate-memory.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable corporate-memory.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start corporate-memory.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop corporate-memory.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-enabled corporate-memory.timer
|
|
|
|
# Allow deploy user to manage jira-sla-poll service and timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/jira-sla-poll.service /etc/systemd/system/jira-sla-poll.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/jira-sla-poll.timer /etc/systemd/system/jira-sla-poll.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable jira-sla-poll.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start jira-sla-poll.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop jira-sla-poll.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-enabled jira-sla-poll.timer
|
|
|
|
# Allow deploy user to manage session-collector service and timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /data/user_sessions
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown root\:data-ops /data/user_sessions
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 2770 /data/user_sessions
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/session-collector.service /etc/systemd/system/session-collector.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/session-collector.timer /etc/systemd/system/session-collector.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable session-collector.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start session-collector.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop session-collector.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-enabled session-collector.timer
|
|
|
|
# Allow deploy user to manage jira-consistency service and timers
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/jira-consistency.service /etc/systemd/system/jira-consistency.service
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/jira-consistency.timer /etc/systemd/system/jira-consistency.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/cp /opt/data-analyst/repo/server/jira-consistency-deep.timer /etc/systemd/system/jira-consistency-deep.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/touch /opt/data-analyst/logs/jira-consistency.log
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown root\:data-ops /opt/data-analyst/logs/jira-consistency.log
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 664 /opt/data-analyst/logs/jira-consistency.log
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable jira-consistency.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start jira-consistency.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop jira-consistency.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-enabled jira-consistency.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl enable jira-consistency-deep.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl start jira-consistency-deep.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop jira-consistency-deep.timer
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-enabled jira-consistency-deep.timer
|
|
|
|
# Allow deploy user to manage data staging directory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/mkdir -p /tmp/data_analyst_staging
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chown root\:data-ops /tmp/data_analyst_staging
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/chmod 2770 /tmp/data_analyst_staging
|
|
|
|
# Allow deploy user to manage ACLs for Jira attachments
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -m g\:dataread\:rx /data/src_data/raw/jira/attachments
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -d -m g\:dataread\:rx /data/src_data/raw/jira/attachments
|
|
|
|
# Allow deploy user to manage ACLs for private parquet directory
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -m g\:data-private\:rx /data/src_data/parquet/private/
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -d -m g\:data-private\:rx /data/src_data/parquet/private/
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -x g\:dataread /data/src_data/parquet/private/
|
|
deploy ALL=(ALL) NOPASSWD: /usr/bin/setfacl -R -d -x g\:dataread /data/src_data/parquet/private/
|
|
|
|
# Allow deploy user to add itself to dataread group (for socket group ownership)
|
|
deploy ALL=(ALL) NOPASSWD: /usr/sbin/usermod -a -G dataread deploy
|