【AWS Systems Manager Parameter Store】パスワードマネージャーアプリ作ってみた
目次
はじめに
はじめまして!
クラウドビルダーズのKawabataと申します。
AWSのParameter Storeを使ってるときに、自分のアカウント情報ここで管理したらよくね?って思ったことありません?
思ったので作ってみました。
Webアプリケーションだと、GoogleのPassword Managerでいいじゃんとなるので、今回は、デスクトップ型パスワードマネージャーにしました。
その開発過程と実装のポイントをご紹介します。
アプリの概要
ソースコード
本アプリケーションのソースコードは、以下のGitHubリポジトリで公開しています:
password-manager-with-aws
READMEにセットアップ手順と使い方を記載しているので、使いたい方はどうぞ
主な機能
- パスワード情報の安全な管理(AWS Parameter Store使用)
- パスワード情報の登録・編集・削除
- クリップボードへのコピー機能
- パスワードのマスク表示
セキュリティ対策
- パスワード情報はAWS Parameter Storeで暗号化して保存
- AWS認証情報はローカルで暗号化して保存
- パスワードはマスク表示がデフォルト
- 30分間操作がない場合は自動ログアウト
- ログイン試行回数の制限(3回まで)
使用技術
フロントエンド
- PyQt6(デスクトップGUI)
バックエンド
- Python 3.10
- AWS SDK (boto3)
- AWS Parameter Store
- cryptography(ローカルでの暗号化)
AWS サービス
- AWS Systems Manager Parameter Store
- AWS IAM(アクセス制御)
- AWS CloudFormation(インフラのコード化)
開発ツール
- Git(バージョン管理)
アプリの作成
1. なぜAWS Parameter Storeを選んだのか?
Parameter Storeには以下のような利点があります:
- 暗号化機能が標準搭載
- アクセス制御が容易(IAM)
- 低コスト(標準パラメータは無料)
- APIによる簡単なアクセス
- バージョン管理機能
とまあ、ありそうな理由を並べましたが、面白そうだからやってみたという側面が強いですw
2. アプリケーションの設計
IAM権限の最小化
アプリケーションで使用するIAM権限はCloudFormationで管理しています:
(ほんとはCDKでやりたかったけどデプロイ面倒なので…)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Password Manager IAM User Setup'
Parameters:
UserName:
Type: String
Description: IAM user name for Password Manager
Resources:
PasswordManagerUser:
Type: AWS::IAM::User
Properties:
UserName: !Ref UserName
Path: "/password-manager/"
PasswordManagerPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub '${UserName}-password-manager-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ssm:PutParameter
- ssm:GetParameter
- ssm:DeleteParameter
- ssm:DescribeParameters
Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/password-manager/${UserName}/*"
このように、Parameter Storeへのアクセスを特定のパス配下のみに制限し、必要最小限の権限のみを付与することで、セキュリティを強化しています。
セキュリティを重視した設計
AWS認証情報は、ローカルで暗号化して保存します。これにより、PCが不正アクセスを受けた場合でも、認証情報は保護されます。
class CredentialsManager:
def __init__(self):
self.config_dir = Path.home() / '.password_manager'
self.credentials_path = self.config_dir / 'credentials.enc'
self._setup_encryption()
使いやすいUI設計
ワンクリックでパスワードをコピーできるなど、日常的な使用を想定した機能を実装しています。
class MainWindow(QMainWindow):
def __init__(self, username: str):
# ...
# パスワードのコピー機能
copy_password_button = QPushButton('パスワードをコピー')
copy_password_button.clicked.connect(
lambda: self.copy_to_clipboard('password')
)
3. セキュリティ対策の実装
自動ログアウト機能
def check_session_timeout(self):
if self.last_activity:
elapsed = datetime.now() - self.last_activity
if elapsed.seconds / 60 >= self.session_timeout:
self.logout()
パスワードの暗号化
パスワード情報はAWS Parameter Storeの SecureString として保存されます。
パラメータ名は /passwords/ユーザー名/アプリ名
の形式で作成されます。
Important: Parameter Storeのパラメータ名には以下の制限があります:
- 使用可能な文字: a-zA-Z0-9_.-
- 最大長: 1011文字
- スラッシュ(/)で階層を表現
そのため、アプリ名には以下の制限があります:
- 英数字、アンダースコア、ハイフン、ピリオドのみ使用可能
- スラッシュは使用不可
- 空白文字は使用不可
def save_password(self, username: str, password_data: dict) -> bool:
parameter_name = f"/passwords/{username}/{password_data['app_name']}"
try:
self.ssm.put_parameter(
Name=parameter_name,
Value=json.dumps(password_data),
Type='SecureString',
Overwrite=True
)
return True
except Exception as e:
print(f"パスワード保存エラー: {e}")
return False
実際に使ってみよう
1. アカウント登録
- アプリケーションを起動すると、ログイン画面が表示されます
- 「新規登録」ボタンをクリックして、登録画面に移動
3. 以下の情報を入力:
- ユーザー名(英数字とハイフン、アンダースコアのみ使用可)
- パスワード(確認用に2回入力)
- AWSアクセスキー(セットアップ時に取得したもの)
- AWSシークレットキー(セットアップ時に取得したもの)
4. 「登録」ボタンをクリックして完了
2. ログイン
- ユーザー名とパスワードを入力
- 「ログイン」ボタンをクリック
3. メイン画面が表示されれば成功!
3. パスワード情報の登録
- メイン画面の「追加」ボタンをクリック
- パスワード情報入力画面で以下を入力:
- アプリ名:「GitHub」
- URL:「https://github.com/login」
- ユーザー名:「myname@example.com」
- パスワード:「your-secure-password」
- メモ:「開発用アカウント」
3. 「保存」ボタンをクリック
4. 一覧に追加されたパスワード情報が表示されます
4. AWS マネジメントコンソールで確認
- AWS マネジメントコンソールにログイン
- Systems Manager > Parameter Store に移動
/passwords/あなたのユーザー名/GitHub
というパラメータが作成されていることを確認
4. パラメータの詳細:
- タイプが「SecureString」になっている
- 暗号化されたJSON形式でデータが保存されている
これで、パスワード情報がAWS上で安全に保管されていることが確認できました!
使用感
実際に使ってみましたが、メリット・デメリットあるなと感じました
良い点
- 操作がシンプル
- パスワードの暗号化が自動的に行われる
- クラウドベースなので複数デバイスでの利用が可能
改善点
- オフライン時は使用できない
- AWS認証情報の管理が必要
- セットアップが少し手間
思い付きで作ったものなのでまだまだ改善の余地はありますねw
おわりに
これDynamoDBでよくね???